From: sharow Date: Mon, 7 Oct 2019 00:34:33 +0000 (+0900) Subject: Add decoder: signature analysis X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=112a2644fdadf17e077a84f63dbbccc87e649a0f;p=libsigrokdecode.git Add decoder: signature analysis --- diff --git a/decoders/signature/__init__.py b/decoders/signature/__init__.py new file mode 100644 index 0000000..d37fd4a --- /dev/null +++ b/decoders/signature/__init__.py @@ -0,0 +1,25 @@ +## +## This file is part of the libsigrokdecode project. +## +## Copyright (C) 2019 Shirow Miura +## +## 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 +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +''' +Signature analysis function for troubleshooting logic circuits. +This generates the same signature as Hewlett-Packard 5004A. +''' + +from .pd import Decoder diff --git a/decoders/signature/pd.py b/decoders/signature/pd.py new file mode 100644 index 0000000..a86878f --- /dev/null +++ b/decoders/signature/pd.py @@ -0,0 +1,139 @@ +## +## This file is part of the libsigrokdecode project. +## +## Copyright (C) 2019 Shirow Miura +## +## 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 +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sigrokdecode as srd + +symbol_map = { + 0b0000: '0', + 0b1000: '1', + 0b0100: '2', + 0b1100: '3', + 0b0010: '4', + 0b1010: '5', + 0b0110: '6', + 0b1110: '7', + 0b0001: '8', + 0b1001: '9', + 0b0101: 'A', + 0b1101: 'C', + 0b0011: 'F', + 0b1011: 'H', + 0b0111: 'P', + 0b1111: 'U', +} + +START, STOP, CLOCK, DATA = range(4) + +class Decoder(srd.Decoder): + api_version = 3 + id = 'signature' + name = 'Signature' + longname = 'Signature analysis' + desc = 'Annotate signature of logic patterns.' + license = 'gplv3+' + inputs = ['logic'] + outputs = [] + tags = ['Debug/trace', 'Util', 'Encoding'] + channels = ( + dict(id='start', name='START', desc='START channel'), + dict(id='stop', name='STOP', desc='STOP channel'), + dict(id='clk', name='CLOCK', desc='CLOCK channel'), + dict(id='data', name='DATA', desc='DATA channel') + ) + options = ( + dict(id='start_edge', desc='Edge-selection for START channel', + default='r', values=('r', 'f')), + dict(id='stop_edge', desc='Edge-selection for STOP channel', + default='r', values=('r', 'f')), + dict(id='clk_edge', desc='Edge-selection for CLOCK channel', + default='f', values=('r', 'f')), + dict(id='annbits', desc='Enable bit level annotation', + default='no', values=('yes', 'no')) + ) + annotations = ( + ('bit0', 'Bit0'), + ('bit1', 'Bit1'), + ('start', 'START'), + ('stop', 'STOP'), + ('sig', 'Sig') + ) + annotation_rows = ( + ('bits', 'Bits', (0, 1, 2, 3)), + ('sig', 'Sig', (4,)) + ) + + def __init__(self): + pass + + def start(self): + self.out_ann = self.register(srd.OUTPUT_ANN) + + def putsig(self, ss, es, signature): + s = ''.join([symbol_map[(signature >> 0) & 0x0f], + symbol_map[(signature >> 4) & 0x0f], + symbol_map[(signature >> 8) & 0x0f], + symbol_map[(signature >> 12) & 0x0f]]) + self.put(ss, es, self.out_ann, [4, [s]]) + + def putb(self, ss, ann): + self.put(ss, self.samplenum, self.out_ann, ann) + + def decode(self): + opt = self.options + start_edge_mode_rising = opt['start_edge'] == 'r' + stop_edge_mode_rising = opt['stop_edge'] == 'r' + annbits = opt['annbits'] == 'yes' + gate_is_open = False + sample_start = None + started = False + last_samplenum = 0 + prev_start = 0 if start_edge_mode_rising else 1 + prev_stop = 0 if stop_edge_mode_rising else 1 + shiftreg = 0 + + while True: + start, stop, _, data = self.wait({CLOCK: opt['clk_edge']}) + if start != prev_start and not gate_is_open: + gate_is_open = (start == 1) if start_edge_mode_rising else (start == 0) + if gate_is_open: + # Start sampling. + sample_start = self.samplenum + started = True + elif stop != prev_stop and gate_is_open: + gate_is_open = not ((stop == 1) if stop_edge_mode_rising else (stop == 0)) + if not gate_is_open: + # Stop sampling. + if annbits: + self.putb(last_samplenum, [3, ['STOP', 'STP', 'P']]) + self.putsig(sample_start, self.samplenum, shiftreg) + shiftreg = 0 + sample_start = None + if gate_is_open: + if annbits: + if started: + s = '<{}>'.format(data) + self.putb(last_samplenum, [2, ['START' + s, 'STR' + s, 'S' + s]]) + started = False + else: + self.putb(last_samplenum, [data, [str(data)]]) + incoming = (bin(shiftreg & 0b0000_0010_1001_0001).count('1') + data) & 1 + shiftreg = (incoming << 15) | (shiftreg >> 1) + prev_start = start + prev_stop = stop + last_samplenum = self.samplenum