SXXXXXXX_PyBusMonitor1553/pybusmonitor1553/lib1553/headers.py
2025-12-11 13:38:49 +01:00

100 lines
2.9 KiB
Python

import ctypes
class UDP1553Header(ctypes.Structure):
"""
Represents the proprietary UDP header wrapping the MIL-STD-1553 frames.
Standard ctypes.Structure uses host endianness (Little Endian on x86/x64).
"""
_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.
Standard Little Endian packing: LSB is first in the bitfield.
Matches C++ struct: wc:5, sa:5, tr:1, rt:5
"""
_pack_ = 1
_fields_ = [
("word_count", ctypes.c_uint16, 5), # Bits 0-4
("subaddress", ctypes.c_uint16, 5), # Bits 5-9
("tr_bit", ctypes.c_uint16, 1), # Bit 10
("remote_terminal", ctypes.c_uint16, 5) # Bits 11-15
]
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
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.
"""
_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