Files
StreamLens/analyzer/protocols/decoders/parallel.py
2025-07-28 08:14:15 -04:00

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'}
)