From 3b19e83780fc293037d17dffa09ea008cdc4c1a9 Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Tue, 14 Feb 2023 17:27:27 +0100
Subject: [PATCH] put terminal into operational later

the Leybold TurboVac does not like to be put into operational unless
it is already getting PDO data. This actually seems like a good idea.
---
 ebpfcat/ebpfcat.py       | 12 +++++++++---
 ebpfcat/ethercat_test.py |  8 ++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/ebpfcat/ebpfcat.py b/ebpfcat/ebpfcat.py
index 7372199..e9f182a 100644
--- a/ebpfcat/ebpfcat.py
+++ b/ebpfcat/ebpfcat.py
@@ -16,7 +16,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 """The high-level API for EtherCAT loops"""
-from asyncio import ensure_future, gather, wait_for, TimeoutError
+from asyncio import ensure_future, gather, sleep, wait_for, TimeoutError
 from contextlib import asynccontextmanager, contextmanager
 import os
 from struct import pack, unpack, calcsize, pack_into, unpack_from
@@ -222,7 +222,7 @@ class EBPFTerminal(Terminal):
             raise RuntimeError(
                 f"Incompatible Terminal: {self.vendorId}:{self.productCode} "
                 f"({relative}, {absolute})")
-        await self.to_operational()
+        await self.to_operational(4)
         self.pdos = {}
         if self.has_mailbox():
             await self.parse_pdos()
@@ -363,6 +363,9 @@ class SyncGroupBase:
         self.terminals = {t: None for t in
                           sorted(terminals, key=lambda t: t.position)}
 
+    async def to_operational(self):
+        await gather(*[t.to_operational() for t in self.terminals])
+
     async def run(self):
         data = self.asm_packet
         while True:
@@ -393,7 +396,9 @@ class SyncGroup(SyncGroupBase):
         self.packet_index = SyncGroup.packet_index
         SyncGroup.packet_index += 1
         self.asm_packet = self.packet.assemble(self.packet_index)
-        return ensure_future(self.run())
+        ret = ensure_future(self.run())
+        ensure_future(self.to_operational())
+        return ret
 
     def allocate(self):
         self.packet = Packet()
@@ -443,6 +448,7 @@ class FastSyncGroup(SyncGroupBase, XDP):
     def start(self):
         self.allocate()
         self.task = ensure_future(self.run())
+        ensure_future(self.to_operational())
         return self.task
 
     def cancel(self):
diff --git a/ebpfcat/ethercat_test.py b/ebpfcat/ethercat_test.py
index e6b93b4..60b6a76 100644
--- a/ebpfcat/ethercat_test.py
+++ b/ebpfcat/ethercat_test.py
@@ -64,17 +64,17 @@ class MockEtherCat:
 class MockTerminal(Terminal):
     async def initialize(self, relative, absolute):
         self.position = absolute
-        self.operational = False
+        self.operational = 1
         data = self.ec.test_data[-relative]
         self.test_eeprom = data["eeprom"]
         self.test_sdo = data["sdo"]
         await self.apply_eeprom()
 
-    async def to_operational(self):
-        self.operational = True
+    async def to_operational(self, state):
+        self.operational = state
 
     async def sdo_read(self, index, subindex=None):
-        assert self.operational
+        assert self.operational >= 2
         if subindex is None:
             r = b''
             for i in count(1):
-- 
GitLab