From 0cf6e5290badc4404964721cc8557b00c0e43cb5 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Thu, 6 Jul 2023 12:01:57 -0400 Subject: [PATCH 01/18] change address hierarchy for multi-rb updates --- tamalero/LPGBT.py | 30 +++++++++++++++--------------- tamalero/ReadoutBoard.py | 18 +++++++++--------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tamalero/LPGBT.py b/tamalero/LPGBT.py index 992e96c..4025b19 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 5e19acf..01a3df0 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): -- GitLab From c252c83228972612b57d7709c549dacfe48427c3 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Fri, 7 Jul 2023 10:25:36 -0400 Subject: [PATCH 02/18] bump required firmware version --- tamalero/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tamalero/__init__.py b/tamalero/__init__.py index 3aaa979..061b0cb 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.0" -- GitLab From 097521241c86c818942d36a4f9fa9c06074aaa64 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Tue, 11 Jul 2023 09:51:26 -0400 Subject: [PATCH 03/18] bump firmware version --- tamalero/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tamalero/__init__.py b/tamalero/__init__.py index 061b0cb..1d6af48 100644 --- a/tamalero/__init__.py +++ b/tamalero/__init__.py @@ -1,2 +1,2 @@ __version__ = "0.1.0" -__fw_version__ = "3.0.0" +__fw_version__ = "3.0.5" -- GitLab From 600c97691db1fd43a8b309437e7971275ddbd5de Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Tue, 11 Jul 2023 16:50:34 -0400 Subject: [PATCH 04/18] update generic address table --- address_table/generic/etl_test_fw.xml | 16 ++++++- address_table/generic/modules/DAQ.xml | 2 +- .../generic/modules/LPGBT_DOWNLINK.xml | 9 +--- .../generic/modules/LPGBT_UPLINK.xml | 28 ----------- .../generic/modules/READOUT_BOARD.xml | 48 ++++++++++++------- address_table/generic/modules/SYSTEM.xml | 15 +++--- 6 files changed, 57 insertions(+), 61 deletions(-) diff --git a/address_table/generic/etl_test_fw.xml b/address_table/generic/etl_test_fw.xml index 29d2f85..ae3fdf4 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 eef446f..c09adf3 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 fadf1d2..f449e8b 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 bc3591b..3bc710e 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 1f2a309..3138f3e 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 f5fee94..7b2051c 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> - -- GitLab From 934cf2fd5813f7d9773757530c1ccadd6542a0a3 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Tue, 11 Jul 2023 17:36:32 -0400 Subject: [PATCH 05/18] bump firmware version --- tamalero/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tamalero/__init__.py b/tamalero/__init__.py index 1d6af48..f82c5ac 100644 --- a/tamalero/__init__.py +++ b/tamalero/__init__.py @@ -1,2 +1,2 @@ __version__ = "0.1.0" -__fw_version__ = "3.0.5" +__fw_version__ = "3.0.6" -- GitLab From b11e38d2bb130b2eb01cf0f107a611fcf9f527b2 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Tue, 11 Jul 2023 17:36:42 -0400 Subject: [PATCH 06/18] better error handling --- tamalero/KCU.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tamalero/KCU.py b/tamalero/KCU.py index 7e35c84..aa5ae9f 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() -- GitLab From d63401dad19a73b1057c6d7b79a951b900b897b0 Mon Sep 17 00:00:00 2001 From: Andrew Peck <andrew.peck@cern.ch> Date: Tue, 11 Jul 2023 17:36:49 -0400 Subject: [PATCH 07/18] add a kcu method to print all registers --- tamalero/KCU.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tamalero/KCU.py b/tamalero/KCU.py index aa5ae9f..8ac9e7d 100644 --- a/tamalero/KCU.py +++ b/tamalero/KCU.py @@ -68,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", -- GitLab From 6aed589ec86d7a62e483876b22ec16a450bd6447 Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Thu, 29 Jun 2023 10:48:42 -0400 Subject: [PATCH 08/18] Modifed etroc_status endpoint to return matrix --- test_tamalero.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/test_tamalero.py b/test_tamalero.py index 4fe22e8..bd25ac4 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -59,20 +59,7 @@ def create_app(rb, modules=[]): for j, etroc in enumerate(module.ETROCs): # 4 ETROCs expected per module if etroc.is_connected(): stat = etroc.pixel_sanity_check(return_matrix=True) - etroc_status[i][j] = {} - for k in range(16): - etroc_status[i][j][k] = {} - for l in range(16): - etroc_status[i][j][k][l] = int(stat[k][l]) - #for j in range(4): - # etroc_status[i*4+j] = {} - # # NOTE here we should get the actual status - # # below is just a placeholder - # for k in range(16): - # etroc_status[i*4+j][k] = {} - # for l in range(16): - # etroc_status[i*4+j][k][l] = 1 - + etroc_status[i][j] = stat.astype(int).tolist() return etroc_status return app -- GitLab From c95eb7d82c237f523dc2713f826a1c76a1719a8e Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Thu, 29 Jun 2023 14:47:16 -0400 Subject: [PATCH 09/18] created threshold endpoint --- test_tamalero.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test_tamalero.py b/test_tamalero.py index bd25ac4..22c595d 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -6,6 +6,10 @@ from tamalero.DataFrame import DataFrame from tamalero.ETROC import ETROC from tamalero.Module import Module +# Import vth_scan function for threshold test endpoint +from test_ETROC import vth_scan + + from tamalero.SCA import SCA_CONTROL import time @@ -62,6 +66,31 @@ def create_app(rb, modules=[]): etroc_status[i][j] = stat.astype(int).tolist() return etroc_status + @app.route('/threshold_test') + def get_threshold_test(): + # These are the default arguments pass when running test_ETROC with --scan full, which runs + # a threshold scan for entire chip + + # vth_scan_data = vth_scan( + # etroc, + # vth_min = 800, + # vth_max = 880, + # decimal = True, + # fifo = fifo, + # absolute = True, + # ) + # vth_axis = np.array(vth_scan_data[0]) + # hit_rate = np.array(vth_scan_data[1]) + # N_pix = len(hit_rate) # total # of pixels + # N_pix_w = int(round(np.sqrt(N_pix))) # N_pix in NxN layout + # max_indices = np.argmax(hit_rate, axis=1) + # maximums = vth_axis[max_indices] + # max_matrix = np.empty([N_pix_w, N_pix_w]) + + + result = "\n You Made Request to Threshold Endpoint \n" + return result + return app if __name__ == '__main__': -- GitLab From 1a04dc0ef63471b45959230aa99dd7d21227e23d Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Thu, 20 Jul 2023 12:04:21 -0400 Subject: [PATCH 10/18] Move instantiation to allow importation of vth_scan into dashboard API --- test_ETROC.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test_ETROC.py b/test_ETROC.py index 26473ef..8ed2f12 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -104,13 +104,12 @@ def vth_scan(ETROC2, vth_min=693, vth_max=709, vth_step=1, decimal=False, fifo=N return [vth_axis.tolist(), run_results.tolist()] -if __name__ == '__main__': - - # initiate - ETROC2 = software_ETROC2() # currently using Software ETROC2 (fake) - print("ETROC2 emulator instantiated, base configuration successful") - DF = DataFrame('ETROC2') +# initiate +ETROC2 = software_ETROC2() # currently using Software ETROC2 (fake) +print("ETROC2 emulator instantiated, base configuration successful") +DF = DataFrame('ETROC2') +if __name__ == '__main__': # argsparser import argparse argParser = argparse.ArgumentParser(description = "Argument parser") -- GitLab From 3370f439d3f032ed3e51a2d7cc377e90bc05e25b Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Thu, 20 Jul 2023 12:16:56 -0400 Subject: [PATCH 11/18] Added threshold scan endpoint to API --- test_tamalero.py | 74 ++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/test_tamalero.py b/test_tamalero.py index 22c595d..8cc48cc 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -6,19 +6,19 @@ from tamalero.DataFrame import DataFrame from tamalero.ETROC import ETROC from tamalero.Module import Module -# Import vth_scan function for threshold test endpoint -from test_ETROC import vth_scan - - from tamalero.SCA import SCA_CONTROL +from test_ETROC import vth_scan, fromPixNum import time import random import sys import os import uhal +import json +import datetime +import numpy as np from emoji import emojize -from flask import Flask +from flask import Flask, request def create_app(rb, modules=[]): # FIXME this should live somewhere else in the future @@ -31,7 +31,9 @@ def create_app(rb, modules=[]): @app.route('/rb_temp') def temperatures(): - return rb.read_temp() + temp = rb.read_temp() + temp['time'] = datetime.datetime.now().isoformat() + return temp @app.route('/module_links') def get_link_status(): @@ -66,30 +68,42 @@ def create_app(rb, modules=[]): etroc_status[i][j] = stat.astype(int).tolist() return etroc_status - @app.route('/threshold_test') - def get_threshold_test(): - # These are the default arguments pass when running test_ETROC with --scan full, which runs - # a threshold scan for entire chip - - # vth_scan_data = vth_scan( - # etroc, - # vth_min = 800, - # vth_max = 880, - # decimal = True, - # fifo = fifo, - # absolute = True, - # ) - # vth_axis = np.array(vth_scan_data[0]) - # hit_rate = np.array(vth_scan_data[1]) - # N_pix = len(hit_rate) # total # of pixels - # N_pix_w = int(round(np.sqrt(N_pix))) # N_pix in NxN layout - # max_indices = np.argmax(hit_rate, axis=1) - # maximums = vth_axis[max_indices] - # max_matrix = np.empty([N_pix_w, N_pix_w]) - - - result = "\n You Made Request to Threshold Endpoint \n" - return result + @app.route('/threshold_scan', methods=['POST']) + def run_threshold_scan(): + payload = json.loads(request.data) + print(f"Threshold Scan on module {payload['module']}, etroc {payload['etroc']}") + + module = modules[int(payload['module'])] + etroc = module.ETROCs[int(payload['etroc'])] + fifo = FIFO(rb=rb_0) + + vth_scan_data = vth_scan( + etroc, + vth_min = 180, + vth_max = 260, + decimal = True, + fifo = fifo, + absolute = True, + ) + + vth_axis = np.array(vth_scan_data[0]) + hit_rate = np.array(vth_scan_data[1]) + N_pix = len(hit_rate) # total # of pixels + N_pix_w = int(round(np.sqrt(N_pix))) # N_pix in NxN layout + max_indices = np.argmax(hit_rate, axis=1) + maximums = vth_axis[max_indices] + max_matrix = np.empty([N_pix_w, N_pix_w]) + + for pix in range(N_pix): + r, c = fromPixNum(pix, N_pix_w) + max_matrix[r][c] = maximums[pix] + + threshold_status = {} + threshold_status['vth_axis'] = vth_axis.tolist() + threshold_status['hit_rate'] = hit_rate.tolist() + threshold_status['max_matrix'] = max_matrix.tolist() + + return threshold_status return app -- GitLab From 0759c2964d65f7dced2acad5366544b4d6bcde5b Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Fri, 21 Jul 2023 13:07:55 -0400 Subject: [PATCH 12/18] disabled threading for API --- test_tamalero.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_tamalero.py b/test_tamalero.py index 8cc48cc..e506405 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -79,8 +79,8 @@ def create_app(rb, modules=[]): vth_scan_data = vth_scan( etroc, - vth_min = 180, - vth_max = 260, + vth_min = 220, + vth_max = 290, decimal = True, fifo = fifo, absolute = True, @@ -281,7 +281,7 @@ if __name__ == '__main__': if args.server: app = create_app(rb_0, modules=modules) - app.run(port=args.port) + app.run(port=args.port, threaded=False) #------------------------------------------------------------------------------- # Read ADCs -- GitLab From b421cb6f2bfcf78b8278be17c9d3636895cf6bbd Mon Sep 17 00:00:00 2001 From: IsaulG3 <mygithub_account@tutanota.com> Date: Mon, 24 Jul 2023 11:33:45 -0400 Subject: [PATCH 13/18] Added Readout Board flag and removed hardcoded board --- test_tamalero.py | 109 +++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/test_tamalero.py b/test_tamalero.py index e506405..c68641e 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,7 @@ 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") args = argParser.parse_args() @@ -150,7 +151,7 @@ if __name__ == '__main__': print ("Using KCU at address: %s"%args.kcu) kcu = None - rb_0 = None + rb = None # 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) @@ -159,21 +160,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 +191,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 +225,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 +239,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 +267,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 +285,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 +294,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 +309,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 +321,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 +346,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) -- GitLab From 1a372888fc6ba7a7c108b257f4f1d6a5e556e565 Mon Sep 17 00:00:00 2001 From: jocain <jgocain@bu.edu> Date: Mon, 24 Jul 2023 14:19:04 -0400 Subject: [PATCH 14/18] Allow KCU.status to show all boards, check for multiple boards in test_tamalero.py --- tamalero/KCU.py | 30 ++++++++++++++++-------------- test_tamalero.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/tamalero/KCU.py b/tamalero/KCU.py index 8ac9e7d..0216718 100644 --- a/tamalero/KCU.py +++ b/tamalero/KCU.py @@ -131,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/test_tamalero.py b/test_tamalero.py index c68641e..8780518 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -138,6 +138,7 @@ if __name__ == '__main__': 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('--multiboard', action = 'store_true') args = argParser.parse_args() @@ -153,6 +154,33 @@ if __name__ == '__main__': kcu = None rb = None + # 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): + # if not basic connection was established the get_kcu function returns 1 + # this would cause the RB init to fail. + sys.exit(1) + + if args.multi_board: + temp = get_kcu(args.kcu, control_hub=args.control_hub, host=args.host, verbose=args.verbose) + if kcu == 0: + sys.exit(1) + for i in range(3): + try: + print(f'Checking ReadoutBoard {i}') + rb = ReadoutBoard(args.rb, trigger=(not args.force_no_trigger), kcu=kcu, config=args.configuration) + + kcu.write_node("LOOPBACK.LOOPBACK", data) + if (data != kcu.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') + + kcu.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): @@ -162,7 +190,7 @@ if __name__ == '__main__': 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) -- GitLab From bdb4d2e736db58c1493ae984b17c6cebefd6a81b Mon Sep 17 00:00:00 2001 From: jocain <jgocain@bu.edu> Date: Mon, 24 Jul 2023 15:03:34 -0400 Subject: [PATCH 15/18] Fixed some typos in test_tamalero.py --multi_board --- test_tamalero.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/test_tamalero.py b/test_tamalero.py index 8780518..8618c72 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -138,7 +138,7 @@ if __name__ == '__main__': 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('--multiboard', action = 'store_true') + argParser.add_argument('--multi_board', action = 'store_true') args = argParser.parse_args() @@ -154,24 +154,17 @@ if __name__ == '__main__': kcu = None rb = None - # 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): - # if not basic connection was established the get_kcu function returns 1 - # this would cause the RB init to fail. - sys.exit(1) - if args.multi_board: temp = get_kcu(args.kcu, control_hub=args.control_hub, host=args.host, verbose=args.verbose) - if kcu == 0: + if temp == 0: sys.exit(1) for i in range(3): try: print(f'Checking ReadoutBoard {i}') - rb = ReadoutBoard(args.rb, trigger=(not args.force_no_trigger), kcu=kcu, config=args.configuration) - - kcu.write_node("LOOPBACK.LOOPBACK", data) - if (data != kcu.read_node("LOOPBACK.LOOPBACK")): + 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}') @@ -180,7 +173,7 @@ if __name__ == '__main__': except: print(f'Connecting to ReadoutBoard {i} failed') - kcu.status() + 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): -- GitLab From 0cbe52154eb06ce3740c133f9267573e44a6d7b6 Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Wed, 26 Jul 2023 14:17:48 -0400 Subject: [PATCH 16/18] data_cnt reset is fixed in FW v3, fixing test_ETROC to be compatible --- test_ETROC.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test_ETROC.py b/test_ETROC.py index 4884280..d23cc9f 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -570,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 = [] @@ -584,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) @@ -601,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) @@ -701,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) @@ -723,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.") @@ -736,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) @@ -804,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) -- GitLab From c787c9ad52411b7c6511d58344d0626cfc59c638 Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Wed, 26 Jul 2023 14:18:50 -0400 Subject: [PATCH 17/18] bumping FW version to v3.0.7 --- tamalero/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tamalero/__init__.py b/tamalero/__init__.py index f82c5ac..7540101 100644 --- a/tamalero/__init__.py +++ b/tamalero/__init__.py @@ -1,2 +1,2 @@ __version__ = "0.1.0" -__fw_version__ = "3.0.6" +__fw_version__ = "3.0.7" -- GitLab From ccd61e321140d40971a78849a0db84641fe7847a Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Wed, 26 Jul 2023 14:21:31 -0400 Subject: [PATCH 18/18] stupid bug, thanks CI --- test_tamalero.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_tamalero.py b/test_tamalero.py index 1a15592..b09b75a 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -260,7 +260,7 @@ 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: -- GitLab