diff --git a/decoders/cec/pd.py b/decoders/cec/pd.py index 84166eb0..ff2d8f24 100644 --- a/decoders/cec/pd.py +++ b/decoders/cec/pd.py @@ -2,6 +2,7 @@ ## This file is part of the libsigrokdecode project. ## ## Copyright (C) 2018 Jorge Solla Rubiales +## Copyright (c) 2022 Marcin Mikula ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -94,6 +95,9 @@ def reset(self): self.fall_start = None self.fall_end = None self.rise = None + self.prev_fall_start = None + self.prev_fall_end = None + self.prev_rise = None self.reset_frame_vars() def reset_frame_vars(self): @@ -112,7 +116,7 @@ def metadata(self, key, value): self.samplerate = value self.precalculate() - def handle_frame(self, is_nack): + def handle_frame(self, is_nack, is_incomplete = 0): if self.fall_start is None or self.fall_end is None: return @@ -148,8 +152,11 @@ def handle_frame(self, is_nack): if i == 1: string += ' | OPC: PING' if self.eom else ' | OPC: NONE. Aborted cmd' - # Add extra information (ack of the command from the destination) - string += ' | R: NACK' if is_nack else ' | R: ACK' + if is_incomplete: + string += ' | INCOMPLETE' + else: + # Add extra information (ack of the command from the destination) + string += ' | R: NACK' if is_nack else ' | R: ACK' self.put(self.frame_start, self.frame_end, self.out_ann, [8, [string]]) @@ -167,24 +174,25 @@ def process(self): # VALIDATION: Invalid pulse if pulse == Pulse.INVALID: self.stat = Stat.WAIT_START - self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['Invalid pulse: Wrong timing']]) + string = 'ERROR: Invalid pulse: Wrong timing (' + str(zero_time) + ')' + self.put(self.fall_start, self.fall_end, self.out_ann, [9, [string]]) return # VALIDATION: If waiting for start, discard everything else if self.stat == Stat.WAIT_START and pulse != Pulse.START: - self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['Expected START: BIT found']]) + self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['ERROR: Expected START: BIT found']]) return # VALIDATION: If waiting for ACK or EOM, only BIT pulses (0/1) are expected if (self.stat == Stat.WAIT_ACK or self.stat == Stat.WAIT_EOM) and pulse == Pulse.START: - self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['Expected BIT: START received)']]) + self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['ERROR: Expected BIT: START received)']]) self.stat = Stat.WAIT_START # VALIDATION: ACK bit pulse remains high till the next frame (if any): Validate only min time of the low period if self.stat == Stat.WAIT_ACK and pulse != Pulse.START: if total_time < timing[pulse]['total']['min']: pulse = Pulse.INVALID - self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['ACK pulse below minimun time']]) + self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['ERROR: ACK pulse below minimun time']]) self.stat = Stat.WAIT_START return @@ -192,8 +200,15 @@ def process(self): if self.stat == Stat.GET_BITS and pulse == Pulse.START: # Make sure we received a complete byte to consider it a valid ping if self.bit_count == 0: - self.handle_frame(self.is_nack) + if self.frame_start is None or self.frame_end is None: + zero_time = ((self.prev_rise - self.prev_fall_start) / self.samplerate) * 1000.0 + total_time = ((self.prev_fall_end - self.prev_fall_start) / self.samplerate) * 1000.0 + string = 'ERROR: Unexpected pulse (' + str(zero_time) + '/' + str(total_time) + ')' + self.put(self.prev_fall_start, self.prev_fall_end, self.out_ann, [9, [string]]) + else: + self.handle_frame(self.is_nack) else: + self.handle_frame(self.is_nack, 1) self.put(self.frame_start, self.samplenum, self.out_ann, [9, ['ERROR: Incomplete byte received']]) # Set wait start so we receive next frame @@ -202,7 +217,8 @@ def process(self): # VALIDATION: Check timing of the BIT (0/1) pulse in any other case (not waiting for ACK) if self.stat != Stat.WAIT_ACK and pulse != Pulse.START: if total_time < timing[pulse]['total']['min'] or total_time > timing[pulse]['total']['max']: - self.put(self.fall_start, self.fall_end, self.out_ann, [9, ['Bit pulse exceeds total pulse timespan']]) + string = 'ERROR: Bit pulse exceeds total pulse timespan (' + str(total_time) +')' + self.put(self.fall_start, self.fall_end, self.out_ann, [9, [string]]) pulse = Pulse.INVALID self.stat = Stat.WAIT_START return @@ -292,6 +308,7 @@ def decode(self): while True: self.wait({0: 'r'}) + self.prev_rise = self.rise self.rise = self.samplenum if self.stat == Stat.WAIT_ACK: @@ -299,6 +316,8 @@ def decode(self): else: self.wait([{0: 'f'}]) + self.prev_fall_start = self.fall_start + self.prev_fall_end = self.fall_end self.fall_start = self.fall_end self.fall_end = self.samplenum self.process() diff --git a/decoders/cec/protocoldata.py b/decoders/cec/protocoldata.py index 78c3b6f5..306c8bd4 100644 --- a/decoders/cec/protocoldata.py +++ b/decoders/cec/protocoldata.py @@ -2,6 +2,7 @@ ## This file is part of the libsigrokdecode project. ## ## Copyright (C) 2018 Jorge Solla Rubiales +## Copyright (c) 2022 Marcin Mikula ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -99,6 +100,13 @@ 0x70: 'SYSTEM_AUDIO_MODE_REQUEST', 0x7E: 'SYSTEM_AUDIO_MODE_STATUS', 0x9A: 'SET_AUDIO_RATE', + 0xC0: 'INITIATE_ARC', + 0xC1: 'REPORT_ARC_INITIATED', + 0xC2: 'REPORT_ARC_TERMINATED', + 0xC3: 'REQUEST_ARC_INITIATION', + 0xC4: 'REQUEST_ARC_TERMINATION', + 0xC5: 'TERMINATE_ARC', + 0xF8: 'CDC_MESSAGE', } def resolve_logical_address(id_, is_initiator):