From ee6dedb6505f85b85f3edfe5816f41712bba5237 Mon Sep 17 00:00:00 2001
From: Bjoern Senfftleben <bjoern.senfftleben@xfel.eu>
Date: Sun, 9 Feb 2025 17:27:27 +0100
Subject: [PATCH] add link states (first test)

---
 src/tempus/Tempus.py | 173 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 160 insertions(+), 13 deletions(-)

diff --git a/src/tempus/Tempus.py b/src/tempus/Tempus.py
index 641f472..fd8fbdf 100644
--- a/src/tempus/Tempus.py
+++ b/src/tempus/Tempus.py
@@ -77,6 +77,17 @@ class Tempus(Device):
         self.channel = None
         self.do_acquire = False
 
+        if self.enableMultiLink:
+            self.LinkStateBottom1 = State.PASSIVE
+            self.LinkStateBottom2 = State.PASSIVE
+            self.LinkStateTop1 = State.PASSIVE
+            self.LinkStateTop2 = State.PASSIVE
+        else:
+            self.LinkStateBottom1 = State.PASSIVE
+            self.LinkStateBottom2 = State.DISABLED
+            self.LinkStateTop1 = State.PASSIVE
+            self.LinkStateTop2 = State.DISABLED
+
     async def _monitor(self):
         last_time = None
         while True:
@@ -153,10 +164,54 @@ class Tempus(Device):
         displayedName="Command Log",
         accessMode=AccessMode.INITONLY)
 
-    enableMultiLink = Bool(
+    @Bool(
         defaultValue=False,
         displayedName="Enable Multiple Data Links",
         allowedStates={State.INIT})
+    async def enableMultiLink(self, value):
+        self.enableMultiLink = value
+        if value:
+            self.LinkStateBottom1 = State.PASSIVE
+            self.LinkStateBottom2 = State.PASSIVE
+            self.LinkStateTop1 = State.PASSIVE
+            self.LinkStateTop2 = State.PASSIVE
+        else:
+            self.LinkStateBottom1 = State.PASSIVE
+            self.LinkStateBottom2 = State.DISABLED
+            self.LinkStateTop1 = State.PASSIVE
+            self.LinkStateTop2 = State.DISABLED
+
+    LinkStateTop1 = String(
+        displayedName="Link State TOP (1)",
+        enum=State,
+        displayType="State",  # This type enables color coding in the GUI
+        description="Reflects the state of a data link from the Timepix4 chip",
+        accessMode=AccessMode.READONLY,
+        defaultValue=State.PASSIVE)
+
+    LinkStateTop2 = String(
+        displayedName="Link State TOP (2)",
+        enum=State,
+        displayType="State",  # This type enables color coding in the GUI
+        description="Reflects the state of a data link from the Timepix4 chip",
+        accessMode=AccessMode.READONLY,
+        defaultValue=State.DISABLED)
+
+    LinkStateBottom1 = String(
+        displayedName="Link State BOTTOM (1)",
+        enum=State,
+        displayType="State",  # This type enables color coding in the GUI
+        description="Reflects the state of a data link from the Timepix4 chip",
+        accessMode=AccessMode.READONLY,
+        defaultValue=State.PASSIVE)
+
+    LinkStateBottom2 = String(
+        displayedName="Link State BOTTOM (1)",
+        enum=State,
+        displayType="State",  # This type enables color coding in the GUI
+        description="Reflects the state of a data link from the Timepix4 chip",
+        accessMode=AccessMode.READONLY,
+        defaultValue=State.DISABLED)
 
     @Slot(
         displayedName="Initialize",
@@ -183,12 +238,25 @@ class Tempus(Device):
                 await self.send_command("mytpx4.initialisechip()", sleep_time=1)
                 await self.send_command("mytpx4.configureGWT()", sleep_time=0.5)
 
-                await self.send_command(
+                link_result = await self.send_command(
                     f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 "
                     "-l 0x0 -s 0x2')", sleep_time=15)  # 0x2 -> 0x1 at the end would double the bandwidth per link to 2.56 Gbit/s instead of 1.28
-                await self.send_command(
+                if "DOWN" in link_result:
+                    self.LinkStateBottom1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom1 = State.ACTIVE
+                else:
+                    self.LinkStateBottom1 = State.UNKNOWN
+
+                link_result = await self.send_command(
                     f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 "
                     "-l 0x0 -s 0x2')", sleep_time=15)  # 0x2 -> 0x1 at the end would double the bandwidth per link to 2.56 Gbit/s instead of 1.28
+                if "DOWN" in link_result:
+                    self.LinkStateTop1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop1 = State.ACTIVE
+                else:
+                    self.LinkStateTop1 = State.UNKNOWN
 
                 await self.send_command("os.system('devmem2 0x80050000 w 0x2')")
             else:
@@ -212,10 +280,37 @@ class Tempus(Device):
                 await self.send_command("mytpx4.initialisechip()", sleep_time=1)
                 await self.send_command("mytpx4.configureGWT()", sleep_time=0.5)
 
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x0 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x3 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x0 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x1 -s 0x2')", sleep_time=15)
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x0 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateBottom1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom1 = State.ACTIVE
+                else:
+                    self.LinkStateBottom1 = State.UNKNOWN
+
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x3 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateBottom2 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom2 = State.ACTIVE
+                else:
+                    self.LinkStateBottom2 = State.UNKNOWN
+                
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x0 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateTop1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop1 = State.ACTIVE
+                else:
+                    self.LinkStateTop1 = State.UNKNOWN
+
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x1 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateTop2 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop2 = State.ACTIVE
+                else:
+                    self.LinkStateTop2 = State.UNKNOWN
 
                 await self.send_command("os.system('devmem2 0x80050000 w 0x2')")
 
@@ -244,20 +339,60 @@ class Tempus(Device):
     async def _reset_fast_links(self, initial_state):
         try:
             if not self.enableMultiLink:
-                await self.send_command(
+                link_result = await self.send_command(
                     f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 "
                     "-l 0x0 -s 0x2')", sleep_time=15)
-                await self.send_command(
+                if "DOWN" in link_result:
+                    self.LinkStateBottom1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom1 = State.ACTIVE
+                else:
+                    self.LinkStateBottom1 = State.UNKNOWN
+                
+                link_result = await self.send_command(
                     f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 "
                     "-l 0x0 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateTop1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop1 = State.ACTIVE
+                else:
+                    self.LinkStateTop1 = State.UNKNOWN
 
                 self.status = "Fast-links reset done"
                 self.state = initial_state
             else:
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x0 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x3 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x0 -s 0x2')", sleep_time=15)
-                await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x1 -s 0x2')", sleep_time=15)
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x0 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateBottom1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom1 = State.ACTIVE
+                else:
+                    self.LinkStateBottom1 = State.UNKNOWN
+
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x0 -l 0x3 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateBottom2 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateBottom2 = State.ACTIVE
+                else:
+                    self.LinkStateBottom2 = State.UNKNOWN
+
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x0 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateTop1 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop1 = State.ACTIVE
+                else:
+                    self.LinkStateTop1 = State.UNKNOWN
+
+                link_result = await self.send_command(f"os.system('{self.APP_DIR}/sc_set_gwt_link_up.py -i 0x1 -l 0x1 -s 0x2')", sleep_time=15)
+                if "DOWN" in link_result:
+                    self.LinkStateTop2 = State.ERROR
+                elif "READY" in link_result:
+                    self.LinkStateTop2 = State.ACTIVE
+                else:
+                    self.LinkStateTop2 = State.UNKNOWN
 
                 self.status = "Fast-links (multi-link) reset done"
                 self.state = initial_state
@@ -371,6 +506,17 @@ class Tempus(Device):
             await self.send_command(
                 f"os.system('{self.APP_DIR}/Timepix4_Init.py')", sleep_time=5)
 
+            if self.enableMultiLink:
+                self.LinkStateBottom1 = State.PASSIVE
+                self.LinkStateBottom2 = State.PASSIVE
+                self.LinkStateTop1 = State.PASSIVE
+                self.LinkStateTop2 = State.PASSIVE
+            else:
+                self.LinkStateBottom1 = State.PASSIVE
+                self.LinkStateBottom2 = State.DISABLED
+                self.LinkStateTop1 = State.PASSIVE
+                self.LinkStateTop2 = State.DISABLED
+
             self.status = "De-initialized"
             self.state = State.INIT
 
@@ -507,6 +653,7 @@ class Tempus(Device):
 
         self.logger.debug(recv.decode())
         self.commandLog = recv.decode()
+        return recv.decode()
 
     def handle_exception(self, e):
         self.logger.error(e)
-- 
GitLab