From 204e23223d08bb70b06c68ccdf4e99f33f08e6f6 Mon Sep 17 00:00:00 2001 From: Martin Teichmann <martin.teichmann@xfel.eu> Date: Sat, 12 Dec 2020 11:04:59 +0000 Subject: [PATCH] working intermediate --- ethercat.py | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/ethercat.py b/ethercat.py index c8ff8a2..a1351a9 100644 --- a/ethercat.py +++ b/ethercat.py @@ -98,6 +98,18 @@ class ObjectEntry: pass +def datasize(args, data): + out = 0 + for arg in args: + if not isinstance(arg, str): + break + out += calcsize(arg) + if isinstance(data, int): + out += data + elif data is not None: + out += len(data) + return out + class AsyncBase: async def __new__(cls, *args, **kwargs): ret = super().__new__(cls) @@ -152,12 +164,14 @@ class EtherCat(Protocol, AsyncBase): elif data is not None: out += data self.send_queue.put_nowait( - (cmd.value, idx, pos, offset, data, future)) + (cmd.value, idx, pos, offset, out, future)) ret = await future if data is None: - return unpack("<" + fmt, ret) + return unpack(fmt, ret) elif args: - return unpack("<" + fmt, ret[:-len(data)]) + (ret[-len(data):],) + if not isinstance(data, int): + data = len(data) + return unpack(fmt, ret[:-data]) + (ret[-data:],) else: return ret @@ -197,8 +211,8 @@ class Terminal: self.mbx_cnt = 1 self.eeprom = await self.read_eeprom() - await self.write(0x800, 0x80) # empty out sync manager - await self.write(0x800, self.eeprom[41]) + await self.write(0x800, data=0x80) # empty out sync manager + await self.write(0x800, data=self.eeprom[41]) self.mbx_out_off, self.mbx_out_sz, self.mbx_in_off, self.mbx_in_sz = \ unpack("<HH4xHH", self.eeprom[41][:12]) @@ -212,13 +226,11 @@ class Terminal: order = [1, 2, 4] #, 8] ret, error = await self.ec.roundtrip( ECCmd.FPRD, self.position, 0x0130, "H2xH") - print(ret, error) if ret & 0x10: await self.ec.roundtrip(ECCmd.FPWR, self.position, 0x0120, "H", 0x11) ret, error = await self.ec.roundtrip(ECCmd.FPRD, self.position, 0x0130, "H2xH") - print("B", ret, error) pos = order.index(ret) s = 0x11 for state in order[pos:]: @@ -234,13 +246,13 @@ class Terminal: return (await self.ec.roundtrip(ECCmd.FPRD, self.position, 0x0134, "H"))[0] - async def read(self, start, fmt, *args, **kwargs): + async def read(self, start, *args, **kwargs): return (await self.ec.roundtrip(ECCmd.FPRD, self.position, - start, fmt, *args, **kwargs)) + start, *args, **kwargs)) - async def write(self, start, fmt, *args, **kwargs): + async def write(self, start, *args, **kwargs): return (await self.ec.roundtrip(ECCmd.FPWR, self.position, - start, fmt, *args, **kwargs)) + start, *args, **kwargs)) async def eeprom_read_one(self, start): """read 8 bytes from the eeprom at start""" @@ -273,13 +285,14 @@ class Terminal: return eeprom eeprom[hd] = await get_data(ws * 2) - async def mbx_send(self, type, data, address=0, priority=0, channel=0): + async def mbx_send(self, type, *args, data=None, address=0, priority=0, channel=0): status, = await self.read(0x805, "B") # always using mailbox 0, OK? if status & 8: raise RuntimeError("mailbox full, read first") - await gather(self.write(self.mbx_out_off, "HHBB", len(data), address, - channel | priority << 6, - type.value | self.mbx_cnt << 4, data=data) + await gather(self.write(self.mbx_out_off, "HHBB", datasize(args, data), + address, channel | priority << 6, + type.value | self.mbx_cnt << 4, + *args, data=data), self.write(self.mbx_out_off + self.mbx_out_sz - 1, data=1) ) self.mbx_cnt = self.mbx_cnt % 7 + 1 # yes, we start at 1 not 0 @@ -295,7 +308,7 @@ class Terminal: async def read_ODlist(self): cmd = pack("<HBxHH", CoECmd.SDOINFO.value << 12, ODCmd.LIST_REQ.value, 0, 1) - await self.mbx_send(MBXType.COE, cmd) + await self.mbx_send(MBXType.COE, data=cmd) fragments = True offset = 8 # skip header in first packet @@ -320,7 +333,7 @@ class Terminal: for index in indexes: cmd = pack("<HBxHH", CoECmd.SDOINFO.value << 12, ODCmd.OD_REQ.value, 0, index) - await self.mbx_send(MBXType.COE, cmd) + await self.mbx_send(MBXType.COE, data=cmd) type, data = await self.mbx_recv() if type is not MBXType.COE: @@ -343,7 +356,7 @@ class Terminal: for i in range(od.maxSub): cmd = pack("<HBxHHBB", CoECmd.SDOINFO.value << 12, ODCmd.OE_REQ.value, 0, od.index, i, 7) - await self.mbx_send(MBXType.COE, cmd) + await self.mbx_send(MBXType.COE, data=cmd) type, data = await self.mbx_recv() if type is not MBXType.COE: -- GitLab