From b3a6437268d57615af72267022a1ddd26ff1fe2f Mon Sep 17 00:00:00 2001
From: Marko Mecina <marko.mecina@univie.ac.at>
Date: Fri, 21 Jul 2023 13:17:19 +0200
Subject: [PATCH] add library for ATHENA DE communication

---
 Ccs/packet_config_ATHENA_DE.py | 602 +++++++++++++++++++++++++++++++++
 1 file changed, 602 insertions(+)
 create mode 100644 Ccs/packet_config_ATHENA_DE.py

diff --git a/Ccs/packet_config_ATHENA_DE.py b/Ccs/packet_config_ATHENA_DE.py
new file mode 100644
index 0000000..2e65983
--- /dev/null
+++ b/Ccs/packet_config_ATHENA_DE.py
@@ -0,0 +1,602 @@
+"""
+Utility functions for communication with ATHENA detector electronics
+
+Ref.: WFI_IAAT_ICD_141210_0001
+      WFI_FP_DesignReport_draft_04Aug21
+
+Author: Marko Mecina (UVIE)
+"""
+
+import ctypes
+from packet_config_ATHENA import RawGetterSetter
+
+
+class EppStates:
+    """
+    EPP FSM states
+    """
+    INIT = 0xFF00
+    STANDBY = 0xFFF0
+    PROGRAM = 0xFF80
+    OGEN = 0xFF8A
+    NGEN = 0xFF8B
+    DIAG_OGEN = 0xFFFA
+    DIAG_NGEN = 0xFFFB
+    DIAG = 0xFFFC
+    WORK = 0xFFFF
+
+
+# dict of states
+EPP_STATES = {k: EppStates.__dict__[k] for k in EppStates.__dict__ if not k.startswith('_')}
+
+
+class IfAddr:
+    """
+    FP interface addresses
+    """
+    HK = 0x33
+    CMD = 0x34
+    SCI = 0x35
+    ECHO = 0x20
+
+
+IF_ADDR = {k: IfAddr.__dict__[k] for k in IfAddr.__dict__ if not k.startswith('_')}
+
+
+class CmdDir:
+    """
+    Write/request ID
+    """
+    SEND = 0x4182
+    RECV = 0xC003
+
+
+# HK & command interface
+
+STRUCT_CMD_PKT = [
+    ("ifaddr", ctypes.c_uint8),
+    ("addr", ctypes.c_uint16),
+    ("txrx", ctypes.c_uint16),
+    ("cmddata", ctypes.c_uint16)
+]
+
+
+class CommandBaseStruct(ctypes.BigEndianStructure):
+    _pack_ = 1
+    _fields_ = [(label, ctype) for label, ctype in STRUCT_CMD_PKT]
+
+    def __init__(self):
+        super(CommandBaseStruct).__init__()
+
+
+CMD_LEN = ctypes.sizeof(CommandBaseStruct)
+ACK_LEN = 3
+SCI_CMD_LEN = 2
+
+
+class CommandBase(ctypes.Union, RawGetterSetter):
+    """
+    Base class for command packets
+    """
+    _pack_ = 1
+    _fields_ = [
+        ('items', CommandBaseStruct),
+        ('bin', ctypes.c_ubyte * CMD_LEN)
+    ]
+
+
+class HkCmdSend(CommandBase):
+
+    def __init__(self, addr, data):
+        super(HkCmdSend).__init__()
+        self.items.ifaddr = IfAddr.HK
+        self.items.addr = addr
+        self.items.txrx = CmdDir.SEND
+        self.items.cmddata = data
+
+
+class HkCmdRecv(CommandBase):
+
+    def __init__(self, addr):
+        super(HkCmdRecv).__init__()
+        self.items.ifaddr = IfAddr.HK
+        self.items.addr = addr
+        self.items.txrx = CmdDir.RECV
+        self.items.cmddata = 0
+
+
+class CmdSend(CommandBase):
+
+    def __init__(self, addr, data):
+        super(CmdSend).__init__()
+        self.items.ifaddr = IfAddr.CMD
+        self.items.addr = addr
+        self.items.txrx = CmdDir.SEND
+        self.items.cmddata = data
+
+
+class CmdRecv(CommandBase):
+
+    def __init__(self, addr):
+        super(CmdRecv).__init__()
+        self.items.ifaddr = IfAddr.CMD
+        self.items.addr = addr
+        self.items.txrx = CmdDir.RECV
+        self.items.cmddata = 0
+
+
+class Ack:
+
+    def __init__(self, raw=bytes(ACK_LEN)):
+        self._raw = raw
+        # self._val = int.from_bytes(raw, 'big')
+
+    def __str__(self):
+        return self._raw.hex().upper()
+
+    @property
+    def ifaddr(self):
+        return self._raw[0]
+
+    @ifaddr.setter
+    def ifaddr(self, addr):
+        self._raw = addr.to_bytes(1, 'big') + self._raw[1:]
+
+    @property
+    def data(self):
+        return self._raw[1:]
+        # return self._val & 0xFFFF
+
+    @data.setter
+    def data(self, d):
+        self._raw = self._raw[:1] + d[:2]
+
+
+class HkPkt:
+
+    def __init__(self, raw):
+        self._raw = raw
+
+    @property
+    def ifaddr(self):
+        return self._raw[0]
+
+
+# Science interface
+EVT_PKT_ELEMENT_LEN = 6  # length of event packet element (timestamp, header, pixel, footer) in bytes
+STRUCT_EVT_PIX = {  # name, bitsize, bitoffset (LSB)
+    "FRAME_N": (8, 40),
+    "ENERGY": (14, 26),
+    "LINE_N": (9, 17),
+    "PIXEL_N": (9, 8),
+    "PFLAGS": (8, 0)
+}
+
+
+class PixProcFlags:
+    """
+    Flags indicating processing steps
+    """
+    PT = 0b10000000
+    T2 = 0b01000000
+    T1 = 0b00100000
+    BM = 0b00010000
+    LT = 0b00001000
+    UT = 0b00000100
+    HP = 0b00000010
+    DP = 0b00000001
+
+
+STRUCT_EVT_HEADER = {
+    "FRAME_N": (8, 40),
+    "HEADER": (32, 8),
+    "INDICTR": (8, 0)
+}
+
+STRUCT_EVT_TIMESTAMP = {
+    "FRAME_N": (8, 40),
+    "SPARE": (2, 38),
+    "SEC": (24, 14),
+    "SUBSEC": (14, 0)
+}
+
+# TBD
+STRUCT_EVT_FOOTER = {}
+
+
+class EvtPktBase:
+    """
+    Base class for event packet elements
+    """
+
+    def __init__(self, byt):
+        assert len(byt) == EVT_PKT_ELEMENT_LEN
+        self._raw = byt
+        self._val = int.from_bytes(byt, 'big')
+
+    @property
+    def raw(self):
+        return self._raw
+
+    @property
+    def frame_n(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["FRAME_N"])
+
+
+class EvtPix(EvtPktBase):
+    """
+    Event Pixel element
+    """
+
+    def __init__(self, raw):
+        super(EvtPix, self).__init__(raw)
+
+    @property
+    def energy(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["ENERGY"])
+
+    @property
+    def line_n(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["LINE_N"])
+
+    @property
+    def pixel_n(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["PIXEL_N"])
+
+    @property
+    def pflags(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"])
+
+    @property
+    def pflags_PT(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.PT) >> 7
+
+    @property
+    def pflags_T2(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.T2) >> 6
+
+    @property
+    def pflags_T1(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.T1) >> 5
+
+    @property
+    def pflags_BM(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.BM) >> 4
+
+    @property
+    def pflags_LT(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.LT) >> 3
+
+    @property
+    def pflags_UT(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.UT) >> 2
+
+    @property
+    def pflags_HP(self):
+        return (_shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.HP) >> 1
+
+    @property
+    def pflags_DP(self):
+        return _shift_mask(self._val, STRUCT_EVT_PIX["PFLAGS"]) & PixProcFlags.DP
+
+
+class EvtHeader(EvtPktBase):
+    """
+    *EventPacket* header
+    """
+
+    def __init__(self, raw):
+        super(EvtHeader, self).__init__(raw)
+
+    @property
+    def header(self):
+        return _shift_mask(self._val, STRUCT_EVT_HEADER["HEADER"])
+
+    @property
+    def header_indicator(self):
+        return _shift_mask(self._val, STRUCT_EVT_HEADER["INDICTR"])
+
+
+class EvtFooter(EvtPktBase):
+    """
+    *EventPacket* footer
+    """
+
+    def __init__(self, raw):
+        super(EvtFooter, self).__init__(raw)
+
+    @property
+    def foo(self):
+        return
+
+
+class EvtTimestamp(EvtPktBase):
+    """
+    *EventPacket* time stamp structure
+    """
+
+    def __init__(self, raw):
+        super(EvtTimestamp, self).__init__(raw)
+
+    @property
+    def spare(self):
+        return _shift_mask(self._val, STRUCT_EVT_TIMESTAMP["SPARE"])
+
+    @property
+    def seconds(self):
+        return _shift_mask(self._val, STRUCT_EVT_TIMESTAMP["SEC"])
+
+    @property
+    def subseconds(self):
+        return _shift_mask(self._val, STRUCT_EVT_TIMESTAMP["SUBSEC"])
+
+
+def _shift_mask(x, bs_os):
+    """
+    Shift and mask packet element to obtain parameter value.
+    
+    :param x: integer value of entire packet element (6 bytes)
+    :type x: int 
+    :param bs_os: size and offset (from LSB) of parameter in bits
+    :type bs_os: tuple
+    :return: 
+    """
+    return (x >> bs_os[1]) & (2 ** bs_os[0] - 1)
+
+
+class EventPacket:
+    """
+    FP science event packet
+    """
+
+    def __init__(self, raw, process=True):
+        self._raw = raw
+        self._len = len(raw)
+        self.pixels_list_proc = None
+
+        self.timestamp = EvtTimestamp(raw[:EVT_PKT_ELEMENT_LEN])
+        self.header = EvtHeader(raw[EVT_PKT_ELEMENT_LEN:2 * EVT_PKT_ELEMENT_LEN])
+        # self._pixels_block = raw[2 * EVT_PKT_ELEMENT_LEN:-EVT_PKT_ELEMENT_LEN]  # if footer is present
+        self._pixels_block = raw[2 * EVT_PKT_ELEMENT_LEN:]
+        self.pixels_list = [self._pixels_block[i:i + EVT_PKT_ELEMENT_LEN] for i in
+                            range(0, len(self._pixels_block), EVT_PKT_ELEMENT_LEN)]
+        # self.footer = EvtFooter(raw[-EVT_PKT_ELEMENT_LEN:])
+
+        if process:
+            self._process_pixels()
+
+    def _process_pixels(self):
+        self.pixels_list_proc = [EvtPix(pix) for pix in self.pixels_list]
+
+
+# delay = 0xXX * sys_clk period
+SCI_DELAY_CONT = 0x00  # continuous transmission
+SCI_DELAY_NOTX = 0xFF  # no transmission
+
+
+class SciCmd:
+
+    def __init__(self, delay):
+        assert 0 <= delay < 256
+        self._raw = ((IfAddr.SCI << 8) + delay).to_bytes(SCI_CMD_LEN, 'big')
+
+    @property
+    def raw(self):
+        return self._raw
+
+    @raw.setter
+    def raw(self, rawdata):
+        self._raw = rawdata
+
+    @property
+    def ifaddr(self):
+        return self._raw[0]
+
+    @property
+    def delay(self):
+        return self._raw[1]
+
+
+def read_de_pkt(pkt, process=True):
+
+    assert isinstance(pkt, (bytes, bytearray))
+
+    p = None
+
+    if pkt[0] == IfAddr.HK:
+        if len(pkt) == ACK_LEN:
+            p = Ack(pkt)
+        elif len(pkt) == CMD_LEN:
+            p = CommandBase(pkt)
+        else:
+            p = HkPkt(pkt)
+    elif pkt[0] == IfAddr.CMD:
+        if len(pkt) == ACK_LEN:
+            p = Ack(pkt)
+        elif len(pkt) == CMD_LEN:
+            p = CommandBase(pkt)
+    elif pkt[0] == IfAddr.SCI and len(pkt) == SCI_CMD_LEN:
+        p = SciCmd(pkt)
+    elif pkt[0] == IfAddr.ECHO:
+        p = pkt
+    elif pkt[0] == IfAddr.SCI and len(pkt[1:]) % EVT_PKT_ELEMENT_LEN == 0:
+        p = EventPacket(pkt[1:], process=process)
+
+    if p is None:
+        raise NotImplementedError('Unknown interface ID {}'.format(pkt[0]))
+
+    return p
+
+
+def split_de_dump(data, de_pkt_size):
+
+    assert isinstance(data, bytes)
+
+    return [data[i:i+de_pkt_size] for i in range(0, len(data), de_pkt_size)]
+
+
+# PCM Registers [TBC]
+PCM_MODE = (0x0000, False, 0x0000)
+PCM_CMD = (0x0000, False, 0x0000)
+PCM_SERIAL_NO = (0x0000, False, 0x0000)
+PCM_HW_VERSION = (0x0000, False, 0x0000)
+PCM_SW_VERSION = (0x0000, False, 0x0000)
+PCM_STATUS = (0x0000, False, 0x0000)
+PCM_PWR_STATUS = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_VSUB = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_A_HI = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_A_LO = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_B_HI = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_B_LO = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_C_HI = (0x0000, False, 0x0000)
+PCM_V_SET_SWA_C_LO = (0x0000, False, 0x0000)
+PCM_V_SET_VRS_VREF = (0x0000, False, 0x0000)
+PCM_V_SET_VRS_VSSS = (0x0000, False, 0x0000)
+PCM_V_SET_VRS_NGATE_SF = (0x0000, False, 0x0000)
+PCM_V_SET_VRS_PGATE_SF = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_DS = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_IS = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_OS = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_R1 = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_R2 = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_BC = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_BC_IGR = (0x0000, False, 0x0000)
+PCM_V_SET_DFT_TEMP_P = (0x0000, False, 0x0000)
+
+# HK Registers [TBC]
+HK_PCM_TEMPERATURE = (0x0000, False, 0x0000)
+HK_V_ACT_PCM_P5V = (0x0000, False, 0x0000)
+HK_I_ACT_PCM_P5V = (0x0000, False, 0x0000)
+HK_V_ACT_PCM_N5V = (0x0000, False, 0x0000)
+HK_I_ACT_PCM_N5V = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_DVDD = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_DVDD = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_VSUB = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_VSUB = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_A_HI = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_A_HI = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_A_LO = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_A_LO = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_B_HI = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_B_HI = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_B_LO = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_B_LO = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_C_HI = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_C_HI = (0x0000, False, 0x0000)
+HK_V_ACT_SWA_C_LO = (0x0000, False, 0x0000)
+HK_I_ACT_SWA_C_LO = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_AVDD = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_AVDD = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_AVSS = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_AVSS = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_DVDD = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_DVDD = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_DVSS = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_DVSS = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_TVDD = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_TVDD = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_TVSS = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_TVSS = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_VREF = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_VREF = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_VSSS = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_VSSS = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_NGATE_SF = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_NGATE_SF = (0x0000, False, 0x0000)
+HK_V_ACT_VRS_PGATE_SF = (0x0000, False, 0x0000)
+HK_I_ACT_VRS_PGATE_SF = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_DS = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_DS = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_IS = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_IS = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_OS = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_OS = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_R1 = (0x0000, False, 0x0000)
+# HK_V_ACT_DFT_R1 = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_R1 = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_R2 = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_R2 = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_BC = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_BC = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_BC_IGR = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_BC_IGR = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_TEMP_GUARD = (0x0000, False, 0x0000)
+HK_I_ACT_DFT_TEMP_GUARD = (0x0000, False, 0x0000)
+HK_V_ACT_DFT_TEMP_P = (0x0000, False, 0x0000)
+
+# Sequencer Registers [TBC]
+SEQ_VER_SPI_MEM = (0x0000, False, 0x0000)
+SEQ_INIT_LEN = (0x0000, False, 0x0000)
+SEQ_INIT_PATCH_LEN = (0x0000, False, 0x0000)
+SEQ_LINE_LEN = (0x0000, False, 0x0000)
+SEQ_LINE_PATCH_LEN = (0x0000, False, 0x0000)
+SEQ_CMD_ACK = (0x0000, False, 0x0000)
+SEQ_MODE = (0x0000, False, 0x0000)
+SEQ_CMD = (0x0000, False, 0x0000)
+SEQ_STARTLINE = (0x0000, False, 0x0000)
+SEQ_STOPLINE = (0x0000, False, 0x0000)
+SEQ_ERROR_CODE = (0x0000, False, 0x0000)
+SEQ_PMEM_A = (0x0000, False, 0x0000)
+SEQ_PMEM_B = (0x0000, False, 0x0000)
+SEQ_LMEM = (0x0000, False, 0x0000)
+
+# EPP registers [TBC]
+EPP_UPPER_THRHLD = (0x0000, False, 0x0000)
+EPP_LOWER_THRHLD = (0x0000, False, 0x0000)
+EPP_PFU_MASK = (0x0000, False, 0x0000)
+EPP_MODE = (0x0000, False, 0x0000)
+EPP_DIAG_RATIO = (0x0000, False, 0x0000)
+EPP_SELECT = (0x0000, False, 0x0000)
+EPP_PFU_SWITCH = (0x0000, False, 0x0000)
+EPP_MLT = (0x0000, False, 0x0000)
+EPP_MHT = (0x0000, False, 0x0000)
+EPP_LTP_SIGMA1 = (0x0000, False, 0x0000)
+EPP_LTP_SIGMA2 = (0x0000, False, 0x0000)
+EPP_PCU_OFFSET_ADDR = (0x0000, False, 0x0000)
+EPP_EFU_OFFSET_ADDR = (0x0000, False, 0x0000)
+EPP_SLICE_SELECT = (0x0000, False, 0x0000)
+EPP_STARTLINE = (0x0000, False, 0x0000)
+EPP_STOPPLINE = (0x0000, False, 0x0000)
+EPP_CTCU_R1 = (0x0000, False, 0x0000)
+EPP_CTCU_R2 = (0x0000, False, 0x0000)
+EPP_CMD = (0x0000, False, 0x0000)
+EPP_PFU_BYPASS = (0x0000, False, 0x0000)
+MSD_TAB_DELAY = (0x0000, False, 0x0000)
+MSD_SPW_DIV = (0x0000, False, 0x0000)
+MSD_SPW_PKG_SIZE = (0x0000, False, 0x0000)
+MSD_ETH_PWR_ADDR_ = (0x0000, False, 0x0000)
+MSD_ETH_BURST_SIZE_ = (0x0000, False, 0x0000)
+MSD_ETH_SELECT_SLICE_ = (0x0000, False, 0x0000)
+MSD_ETH_SELECT_MODULE_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_SOURCE_0_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_SOURCE_1_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_SOURCE_2_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_DESTIN_0_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_DESTIN_1_ = (0x0000, False, 0x0000)
+MSD_ETH_MAC_DESTIN_2_ = (0x0000, False, 0x0000)
+MSD_ETH_IP_SOURCE_0_ = (0x0000, False, 0x0000)
+MSD_ETH_IP_SOURCE_1_ = (0x0000, False, 0x0000)
+MSD_ETH_IP_DESTIN_0_ = (0x0000, False, 0x0000)
+MSD_ETH_IP_DESTIN_1_ = (0x0000, False, 0x0000)
+MSD_ETH_UDP_SOURCE_ = (0x0000, False, 0x0000)
+MSD_ETH_UDP_DESTIN_ = (0x0000, False, 0x0000)
+
+# EPP SUB-registers [TBC]
+SRAM_FIFO3_SLICE0 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE1 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE2 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE3 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE4 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE5 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE6 = (0x0000, False, 0x0000)
+SRAM_FIFO3_SLICE7 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE0 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE1 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE2 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE3 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE4 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE5 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE6 = (0x0000, False, 0x0000)
+SRAM_FIFO2_SLICE7 = (0x0000, False, 0x0000)
+DIAG_GOOD_RAM = (0x0000, False, 0x0000)
+DIAG_BAD_RAM = (0x0000, False, 0x0000)
-- 
GitLab