SXXXXXXX_PyBusMonitor1553/pybusmonitor1553/lib1553/headers.py
2025-12-09 15:52:18 +01:00

103 lines
3.1 KiB
Python

import ctypes
class UDP1553Header(ctypes.Structure):
"""
Represents the proprietary UDP header wrapping the MIL-STD-1553 frames.
Based on the provided reference implementation.
"""
_pack_ = 1
_fields_ = [
("marker1553", ctypes.c_uint16),
("vmajor", ctypes.c_uint8),
("vminor", ctypes.c_uint8),
("otype", ctypes.c_uint16),
("ta", ctypes.c_uint8),
("flags", ctypes.c_uint8),
("fcounter", ctypes.c_uint32),
("mcounter", ctypes.c_uint32),
("scounter", ctypes.c_uint32),
("mmiss", ctypes.c_uint32),
("smiss", ctypes.c_uint32),
("ltt", ctypes.c_uint32),
("errors", ctypes.c_uint32),
("bc_reserved", ctypes.c_uint32 * 2),
("rt_reserved", ctypes.c_uint32 * 2),
("spare", ctypes.c_uint32 * 3)
]
# Constants identifying the packet structure
MARKER_1553 = 0x1553
MARKER_END_1553 = 0x5315
OTYPE_BC = 0x4342
OTYPE_RT = 0x5452
# Error codes
ERR_UNSUPPORTED_VERSION = 1
ERR_INVALID_SOURCE = 2
ERR_INVALID_LEN = 3
ERR_MISSED_MSG_MARKER = 4
def __init__(self, **kwargs):
super().__init__(**kwargs)
if "marker1553" not in kwargs:
self.marker1553 = self.MARKER_1553
if "otype" not in kwargs:
self.otype = self.OTYPE_BC
class CommandWordStruct(ctypes.Structure):
"""
Bit-field representation of a 1553 Command Word.
"""
_pack_ = 1
_fields_ = [
("word_count", ctypes.c_uint16, 5), # Bit 0-4: Word Count / Mode Code
("subaddress", ctypes.c_uint16, 5), # Bit 5-9: Subaddress
("tr_bit", ctypes.c_uint16, 1), # Bit 10: Transmit/Receive (1=Tx)
("remote_terminal", ctypes.c_uint16, 5)# Bit 11-15: Remote Terminal Address
]
class CommandWordUnion(ctypes.Union):
"""
Union to access Command Word as raw integer or bit-fields.
"""
_pack_ = 1
_fields_ = [
("raw", ctypes.c_uint16),
("struct", CommandWordStruct)
]
def __init__(self, rt_addr=0, sub_addr=0, word_count=0, transmit=False):
super().__init__()
self.struct.remote_terminal = rt_addr
self.struct.subaddress = sub_addr
# According to 1553B, word count 0 usually means 32 words,
# but logic here depends on specific implementation.
# We store the value 0-31 directly.
self.struct.word_count = word_count & 0x1F
self.struct.tr_bit = 1 if transmit else 0
class UDP1553MessageHeader(ctypes.Structure):
"""
Header for a single 1553 Message inside the UDP packet payload.
Followed immediately by the raw data words (not included in this struct).
"""
_pack_ = 1
_fields_ = [
("marker", ctypes.c_uint16),
("command_word", CommandWordUnion),
("status_word", ctypes.c_uint16),
("error_code", ctypes.c_uint16)
]
MARKER_BEGIN = 0x3C3C
MARKER_END = 0x3E3E
def __init__(self, command_word_union=None):
super().__init__()
self.marker = self.MARKER_BEGIN
if command_word_union:
self.command_word = command_word_union
self.error_code = 0