diff --git a/radar_data_reader/core/data_structures.py b/radar_data_reader/core/data_structures.py index d3395b4..c6ba727 100644 --- a/radar_data_reader/core/data_structures.py +++ b/radar_data_reader/core/data_structures.py @@ -505,6 +505,7 @@ class TimerRawIf(CtypesStructureBase): """ _fields_ = [ + # --- Part 1 & 2: Confirmed Stable (fino a offset 0x280) --- ("tcr", ctypes.c_uint32), ("tpr", ctypes.c_uint32), ("tor", ctypes.c_uint32), @@ -513,21 +514,23 @@ class TimerRawIf(CtypesStructureBase): ("diff_prt_num", ctypes.c_uint16), ("spares__", ctypes.c_uint32 * 3), ("shift", ShiftRegisters), - ("spare_after_shift", ctypes.c_byte * (12)), # Padding fino a 0x50 - # Offset in C++: 0x50 - ( - "aesa_delay", - UniquePrtFifo * 2, - ), # Dimensione: 64 bytes * 2 = 128 bytes. Va da 0x50 a 0xD0 - ( - "spare0__", - ctypes.c_byte * 48, - ), # Padding per raggiungere 0x100 (da 0xD0 a 0x100) - # Offset in C++: 0x100 - ("exp_pulse1_delay", UniquePrtFifo * 2), # da 0x100 a 0x180 - ("exp_pulse2_delay", UniquePrtFifo * 2), # da 0x180 a 0x200 - # Offset in C++: 0x200 - ("pretrigger_det_delay", UniquePrtFifo * 2), # da 0x200 a 0x280 + ("spare_after_shift", ctypes.c_byte * 12), + ("aesa_delay", UniquePrtFifo * 2), + ("spare0__", ctypes.c_byte * 48), + ("exp_pulse1_delay", UniquePrtFifo * 2), + ("exp_pulse2_delay", UniquePrtFifo * 2), + ("pretrigger_det_delay", UniquePrtFifo * 2), + + # --- Part 3: New Expansion --- + # Offset in C++: 0x280 + ("rx_synch", DelayWithPeriod * 2), + + # Offset: 0x280 + sizeof(DelayWithPeriod * 2) -> 0x400 + ("cf_synch", DelayWithPeriod * 2), + + # Offset: 0x400 + sizeof(DelayWithPeriod * 2) -> 0x580 + ("ew_synch", DelayWithPeriod * 2), + # Il resto รจ omesso per ora ] diff --git a/radar_data_reader/core/struct_parser.py b/radar_data_reader/core/struct_parser.py index 011ebeb..0f6297f 100644 --- a/radar_data_reader/core/struct_parser.py +++ b/radar_data_reader/core/struct_parser.py @@ -85,46 +85,40 @@ def _parse_cdpsts_block( ) -def _parse_timer_block( - block_data_bytes: bytes, block_name: str, block_size_words: int -) -> ds.TimerBlock: +def _parse_timer_block(block_data_bytes: bytes, block_name: str, block_size_words: int) -> ds.TimerBlock: """ Parses a TIMER block by mapping it to the GrifoTimerBlob ctypes structure. + This version flexibly handles blocks that may be smaller than the full struct size. """ - required_size = ctypes.sizeof(ds.GrifoTimerBlob) - if len(block_data_bytes) < required_size: - log.warning( - f"TIMER block is too small for GrifoTimerBlob. Size: {len(block_data_bytes)}, Required: {required_size}" - ) - return ds.TimerBlock( - block_name=block_name, block_size_words=block_size_words, is_valid=False - ) + full_struct_size = ctypes.sizeof(ds.GrifoTimerBlob) + actual_block_size = len(block_data_bytes) + + # We can only map the data that is actually present in the file. + mappable_size = min(full_struct_size, actual_block_size) + + # We still need at least the header to proceed. + header_size = ctypes.sizeof(ds.GrifoFwBlobHeader) + if actual_block_size < header_size: + log.warning(f"TIMER block is too small to even contain a header. Size: {actual_block_size}") + return ds.TimerBlock(block_name=block_name, block_size_words=block_size_words, is_valid=False) try: - timer_blob = ds.GrifoTimerBlob.from_buffer_copy(block_data_bytes) - - # Validate using the internal header marker - is_valid = ( - timer_blob.hdr.header_marker == 0x12345678 - and timer_blob.hdr.sub_marker == 0x54494D45 - ) # 'TIME' + # Create an empty instance of the full struct first + timer_blob = ds.GrifoTimerBlob() + + # Copy the available data from the file into our struct instance + ctypes.memmove(ctypes.addressof(timer_blob), block_data_bytes, mappable_size) + + # Validate using the internal header marker, which should always be present. + is_valid = (timer_blob.hdr.header_marker == 0x12345678 and timer_blob.hdr.sub_marker == 0x54494D45) # 'TIME' if not is_valid: - log.debug( - "TIMER block has an invalid internal Grifo FW blob header marker." - ) - - return ds.TimerBlock( - block_name=block_name, - block_size_words=block_size_words, - is_valid=is_valid, - blob=timer_blob, - ) + log.debug("TIMER block has an invalid internal Grifo FW blob header marker.") + + return ds.TimerBlock(block_name=block_name, block_size_words=block_size_words, is_valid=is_valid, blob=timer_blob) except Exception as e: log.error(f"Failed to map data to GrifoTimerBlob: {e}", exc_info=True) - return ds.TimerBlock( - block_name=block_name, block_size_words=block_size_words, is_valid=False - ) + return ds.TimerBlock(block_name=block_name, block_size_words=block_size_words, is_valid=False) def _parse_signal_block(