From d1714cb0bf7831a64da6ec1d91b8797140079b3d Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Sat, 6 Apr 2024 16:42:36 +0000
Subject: [PATCH] add some documentation of ec-info

and also improve its output a bit
---
 ebpfcat/ethercat.py  |   6 +-
 ebpfcat/ethercat.rst | 165 +++++++++++++++++++++++++++++++++++++++++++
 ebpfcat/scripts.py   |   4 +-
 3 files changed, 171 insertions(+), 4 deletions(-)

diff --git a/ebpfcat/ethercat.py b/ebpfcat/ethercat.py
index f9c1f43..9169941 100644
--- a/ebpfcat/ethercat.py
+++ b/ebpfcat/ethercat.py
@@ -195,8 +195,10 @@ class ObjectEntry:
         if self.name is None:
             return "[unread ObjectEntry]"
 
-        return f'"{self.name}" {self.dataType}:{self.bitLength} ' \
-               f'{self.objectAccess:X}'
+        dt = self.dataType
+        return f'{self.name} ' \
+               f'{dt.name if isinstance(dt, ECDataType) else dt} ' \
+               f'({self.bitLength} bit) flags {self.objectAccess:X}'
 
 
 def datasize(args, data):
diff --git a/ebpfcat/ethercat.rst b/ebpfcat/ethercat.rst
index 9439836..0389023 100644
--- a/ebpfcat/ethercat.rst
+++ b/ebpfcat/ethercat.rst
@@ -174,6 +174,171 @@ A complete example of a four channel terminal looks as follows::
         channel4 = Channel(0x30)
 
 
+Inspecting the bus via the command line
+---------------------------------------
+
+.. highlight:: BashSession
+
+Using the command line tool ``ec-info`` one can learn many details about the
+terminals on an EtherCat bus. As its first parameter, it always takes the
+interface the bus is connected to, in the following examples we always take
+``eth0``. The ``--terminal`` (or ``-t``) parameter may be used with the
+position of the terminal on the bus to be inspected, otherwise all terminals
+will be inspected. All other parameters indicate which information should be
+shown.
+
+The ``--ids`` (or ``-i``) parameter shows the identification numbers of the
+terminal from its EEPROM. As an example::
+
+    $ sudo ec-info eth0 -i -t3
+    terminal no 3
+    2:1B813052 revision 100034 serial 0
+
+This means that terminal number 3 has vendor ID 2 (that is Beckhoff
+Automation), with product code 0x1B813052 (an EL7041 terminal), revision
+0x100034 and serial number 0. Note that most vendors will leave the serial
+number 0, though in principle this can be changed.
+
+The ``--names`` (or ``-n``) parameter shows some readable text found in the
+EEPROM of the terminal. This may be anything, but often is helpful in
+identifying the terminal::
+
+    $ sudo ec-info eth0 -n -t12
+    terminal no 12
+    EL7031
+    DriveAxisTerminals
+    Antriebs- und Achsklemmen (EL7xxx)
+    EL7031 1K. Schrittmotor-Endstufe (24V, 1.5A)
+    Synchron
+    DC
+
+A little less user friendly, but sometimes more informative variant is the
+``--eeprom`` (or ``-e``) parameter, showing the content of the sections of the
+EEPROM once as text and once as a hexadecimal representation::
+
+    $ sudo ec-info eth0 -e -t12
+    terminal no 12
+     3: b'1P079532SBTN000jb1061KES7031                        Q1    2P242213130026'
+        31503037393533325342544e3030306a62313036314b4553373033312020202020202020202020202020202020202020202020205131202020203250323432323133313330303236
+    10: b'\x06\x06EL7031\x12DriveAxisTerminals"Antriebs- und Achsklemmen (EL7xxx),EL7031 1K. Schrittmotor-Endstufe (24V, 1.5A)\x08Synchron\x02DC\xff'
+        0606454c37303331124472697665417869735465726d696e616c7322416e7472696562732d20756e6420416368736b6c656d6d656e2028454c37787878292c454c3730333120314b2e20536368726974746d6f746f722d456e64737475666520283234562c20312e3541290853796e6368726f6e024443ff
+    30: b"\x02\x00\x01\x04\x0c'\x01\x00\x00\x00\x00\x04x\x00\x03\x003\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        020001040c270100000000047800030033000000000000000000000000000000
+    40: b'\x01\x02\x03\xff'
+        010203ff
+    41: b'\x00\x10\x80\x00&\x00\x01\x01\x80\x10\x80\x00"\x00\x01\x02\x00\x11\x08\x00$\x00\x01\x03\x80\x11\x08\x00 \x00\x01\x04'
+        0010800026000101801080002200010200110800240001038011080020000104
+    60: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x01\x00\x06\x00\x00\x00\x00\x00'
+        000000000000000000000000000000000000050000000000000000000000000000000000000000030100060000000000
+
+Using the ``--pdo`` (or ``-p``) parameter one can inspect the current PDO configuration, this are the CoE parameters available for synchronous read and write::
+
+    $ sudo ec-info eth0 -p -t12
+    terminal no 12
+    7000:02 OUT 0 1
+    7000:03 OUT 0 2
+    7000:04 OUT 0 3
+    7000:11 OUT 2 H
+    7010:01 OUT 4 0
+    7010:02 OUT 4 1
+    7010:03 OUT 4 2
+    7010:21 OUT 6 H
+    6000:02 IN 0 1
+    6000:03 IN 0 2
+    6000:04 IN 0 3
+    ...
+
+The first columns shows the CoE address, the second shows OUT for data written
+to the terminal, IN for those read from it. The third column indicates the byte
+adress in the synchronous datagram, and the last column either the bit within
+that byte, or an indicator of the ssize of the parameter. The meaning of the
+parameters can be found in the terminal's documentation, or possibly via the
+``--sdo`` parameter.
+
+The CoE adresses shown here following a pattern that at least Beckhoff
+Automation follows: the 7xxx:xx range are the output parameters, the 6xxx:xx
+range are the input parameters.
+
+The ``--sdo`` (or ``-s``) paramter shows the terminal's self description of
+parameters. This self description, however, varies in quality depending on the
+vendor. Let's go through some of the output::
+
+    $ sudo ec-info eth0 -s -t12
+    terminal no 12
+    1000:
+        0: Device type UNSIGNED32 (32 bit) flags 7
+    1008:
+        0: Device name VISIBLE_STRING (48 bit) flags 7
+    1009:
+        0: Hardware version VISIBLE_STRING (16 bit) flags 7
+    100A:
+        0: Software version VISIBLE_STRING (16 bit) flags 7
+    1011:
+        1: SubIndex 001 UNSIGNED32 (32 bit) flags 3F
+    1018:
+        1: Vendor ID UNSIGNED32 (32 bit) flags 7
+        2: Product code UNSIGNED32 (32 bit) flags 7
+        3: Revision UNSIGNED32 (32 bit) flags 7
+        4: Serial number UNSIGNED32 (32 bit) flags 7
+    ...
+
+The output usually starts with some identification of the device itself. Note
+that the output is grouped by CoE groups, so in the example the adress of the
+serial number (last line) would be 1018:4. Adding the ``--values`` (or ``-v``)
+parameter also shows the current values of the CoE parameter, for numbers both
+in decimal and hexadecimal::
+
+    $ sudo ec-info eth0 -s -v -t12
+    terminal no 12
+    1000:
+        0: Device type UNSIGNED32 (32 bit) flags 7
+                  5001     1389
+    1008:
+        0: Device name VISIBLE_STRING (48 bit) flags 7
+            ES7031
+            'ES7031'
+    1009:
+        0: Hardware version VISIBLE_STRING (16 bit) flags 7
+            13
+            '13'
+    100A:
+        0: Software version VISIBLE_STRING (16 bit) flags 7
+            13
+            '13'
+    1011:
+        1: SubIndex 001 UNSIGNED32 (32 bit) flags 3F
+                     0        0
+    1018:
+        1: Vendor ID UNSIGNED32 (32 bit) flags 7
+                     2        2
+        2: Product code UNSIGNED32 (32 bit) flags 7
+             460795986 1B773052
+        3: Revision UNSIGNED32 (32 bit) flags 7
+               1703936   1A0000
+        4: Serial number UNSIGNED32 (32 bit) flags 7
+                 72315    11A7B
+    ...
+
+Later on, the actual functionality of the terminal is shown. As an example, a
+stepper motor terminal might be enabled with a boolean value, and a velocity
+may be set::
+
+    7010:
+        1: Enable BOOLEAN (1 bit) flags 47
+                     0        0
+        2: Reset BOOLEAN (1 bit) flags 47
+                     0        0
+        3: Reduce torque BOOLEAN (1 bit) flags 47
+                     0        0
+        11: Position UNSIGNED32 (32 bit) flags 47
+                     0        0
+        21: Velocity INTEGER16 (16 bit) flags 47
+                     0        0
+
+So in this example, CoE address 7010:21 is a 16 bit integer that sets the drive
+velocity of a stepper motor.
+
+
 Reference Documentation
 -----------------------
 
diff --git a/ebpfcat/scripts.py b/ebpfcat/scripts.py
index 20a66c3..e8c090e 100644
--- a/ebpfcat/scripts.py
+++ b/ebpfcat/scripts.py
@@ -56,7 +56,7 @@ async def info():
         await term.initialize(-args.terminal, free)
         terms = [term]
 
-    for i, t in enumerate(terms):
+    for i, t in enumerate(terms, args.terminal if args.terminal else 0):
         print(f"terminal no {i}")
         if args.ids:
             print(f"{t.vendorId:X}:{t.productCode:X} "
@@ -94,7 +94,7 @@ async def info():
             await t.to_operational(MachineState.PRE_OPERATIONAL)
             await t.parse_pdos()
             for (idx, subidx), (sm, pos, fmt) in t.pdos.items():
-                print(f"{idx:4X}:{subidx:02X} {sm} {pos} {fmt}")
+                print(f"{idx:4X}:{subidx:02X} {sm.name} {pos} {fmt}")
 
 
 def encode(name):
-- 
GitLab