83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
"""
|
|
Parallel Data decoder for Chapter 10 data types
|
|
Supports Parallel Data Format 0 (0x60)
|
|
"""
|
|
|
|
import struct
|
|
from typing import Dict, Any, Optional
|
|
from .base import DataTypeDecoder, DecodedPayload
|
|
|
|
|
|
class ParallelDecoder(DataTypeDecoder):
|
|
"""Decoder for Parallel Data type (0x60)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.data_type_base = 0x60
|
|
self.data_type_name = "Parallel Data"
|
|
self.supported_formats = [0x60]
|
|
|
|
def can_decode(self, data_type: int) -> bool:
|
|
return data_type == 0x60
|
|
|
|
def get_data_type_name(self, data_type: int) -> str:
|
|
return "Parallel Data Format 0"
|
|
|
|
def decode(self, payload: bytes, ch10_header: Dict[str, Any]) -> Optional[DecodedPayload]:
|
|
"""Decode Parallel Data payload"""
|
|
decoded_data = {}
|
|
errors = []
|
|
|
|
# Parse IPH
|
|
iph = self._parse_intra_packet_header(payload)
|
|
if iph:
|
|
decoded_data.update(iph)
|
|
data_start = iph['data_start']
|
|
else:
|
|
data_start = 0
|
|
errors.append("Failed to parse intra-packet header")
|
|
|
|
# Parse parallel data header
|
|
if data_start + 8 <= len(payload):
|
|
par_header = self._safe_unpack('<II', payload, data_start)
|
|
if par_header:
|
|
decoded_data.update({
|
|
'parallel_timestamp': par_header[0],
|
|
'parallel_status': par_header[1]
|
|
})
|
|
|
|
# Decode status bits
|
|
status = par_header[1]
|
|
decoded_data['data_valid'] = bool(status & 0x01)
|
|
decoded_data['clock_valid'] = bool(status & 0x02)
|
|
decoded_data['sync_detected'] = bool(status & 0x04)
|
|
decoded_data['error_detected'] = bool(status & 0x08)
|
|
|
|
# Extract parallel data
|
|
par_data_start = data_start + 8
|
|
if par_data_start < len(payload):
|
|
par_data = payload[par_data_start:]
|
|
decoded_data['parallel_data_length'] = len(par_data)
|
|
decoded_data['parallel_data_hex'] = par_data[:128].hex()
|
|
|
|
# Analyze data patterns
|
|
if len(par_data) >= 4:
|
|
# Sample first few words
|
|
words = []
|
|
for i in range(0, min(len(par_data), 32), 4):
|
|
if i + 4 <= len(par_data):
|
|
word = struct.unpack('<I', par_data[i:i+4])[0]
|
|
words.append(f'0x{word:08x}')
|
|
decoded_data['sample_words'] = words
|
|
else:
|
|
errors.append("Failed to parse parallel data header")
|
|
|
|
return DecodedPayload(
|
|
data_type=0x60,
|
|
data_type_name="Parallel Data Format 0",
|
|
format_version=0,
|
|
decoded_data=decoded_data,
|
|
raw_payload=payload,
|
|
errors=errors,
|
|
metadata={'decoder': 'ParallelDecoder'}
|
|
) |