100 lines
2.9 KiB
Python
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 |