import ctypes from .constants import Marker, OType, ErrorCode class Udp1553Header(ctypes.Structure): """ Header structure for the UDP encapsulation of 1553 messages. """ _pack_ = 1 _fields_ = [ ("marker_1553", ctypes.c_uint16), ("v_major", ctypes.c_uint8), ("v_minor", ctypes.c_uint8), ("o_type", ctypes.c_uint16), ("ta", ctypes.c_uint8), ("flags", ctypes.c_uint8), ("frame_counter", ctypes.c_uint32), ("msg_counter", ctypes.c_uint32), ("spare_counter", ctypes.c_uint32), ("m_miss", ctypes.c_uint32), ("s_miss", 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) ] def __init__(self): super().__init__() self.marker_1553 = Marker.START_1553 self.o_type = OType.BC self.ltt = 0 class CommandWordStr(ctypes.Structure): _pack_ = 1 _fields_ = [ ("wc", ctypes.c_ushort, 5), # Word Count ("sa", ctypes.c_ushort, 5), # Sub Address ("tr", ctypes.c_ushort, 1), # Transmit/Receive ("rt", ctypes.c_ushort, 5) # Remote Terminal Address ] class CommandWord(ctypes.Union): """ MIL-STD-1553 Command Word Union. Allows access via raw uint16 or bitfields. """ _pack_ = 1 _fields_ = [ ("raw", ctypes.c_uint16), ("fields", CommandWordStr) ] def __init__(self, wc=0, sa=0, tr=0, rt=0): super().__init__() self.fields.wc = wc if wc != 32 else 0 self.fields.sa = sa self.fields.tr = tr self.fields.rt = rt class StatusWordStr(ctypes.Structure): _pack_ = 1 _fields_ = [ ("tf", ctypes.c_ushort, 1), # Terminal Flag ("bca", ctypes.c_ushort, 1), # Broadcast Command Received ("sf", ctypes.c_ushort, 1), # Subsystem Flag ("busy", ctypes.c_ushort, 1), # Busy ("brcs", ctypes.c_ushort, 1), # Broadcast Command Received ("reserved", ctypes.c_ushort, 3), ("sr", ctypes.c_ushort, 1), # Service Request ("instr", ctypes.c_ushort, 1), # Instrumentation ("me", ctypes.c_ushort, 1), # Message Error ("rt", ctypes.c_ushort, 5), # Remote Terminal Address ] class StatusWord(ctypes.Union): """ MIL-STD-1553 Status Word Union. """ _pack_ = 1 _fields_ = [ ("raw", ctypes.c_uint16), ("fields", StatusWordStr) ] class Udp1553Message(ctypes.Structure): """ Represents the metadata wrapping the actual payload in the UDP packet. Corresponds to udp_1553_msg_t in the previous code. """ _pack_ = 1 _fields_ = [ ("marker", ctypes.c_uint16), ("cw", CommandWord), ("sw", ctypes.c_uint16), # Status word is often just passed as raw here ("error_code", ctypes.c_uint16) ] def __init__(self, marker=Marker.CTRL_BEGIN, cw=None, sw=0, error_code=ErrorCode.OK): super().__init__() self.marker = marker if cw: self.cw = cw self.sw = sw self.error_code = error_code