From 41e0dd7ae3d5587011ea7f37f5dc83b232fa5373 Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Sat, 2 May 2020 15:49:05 +0200 Subject: sae_j1850_vpw: update for API v3, adjust to recent requirements IRC user pman92 reported that this decoder exists, and started migration to the v3 API. This commit completes the migration, and adds missing decoder infrastructure which has become mandatory recently. Adjust the boilerplate: Drop FSF postal address. No Python output, add category tag, unambiguous annotation class and row names. Add reset() method. Use common code for edge detection. This commit also addresses minor style nits. Pass the most recent pulse's edges as ss and es to the data bit handling routine. Adjust whitespace to unbreak editor navigation and to improve readability. Use a more verbose name for the decoder, "vpw" appears a little short and collision happy, and is not found when users search for "j1850". [ Indentation changed, see whitespace ignoring diff for the essence. ] Reported-By: pman92 --- decoders/vpw/__init__.py | 25 ------- decoders/vpw/pd.py | 184 ----------------------------------------------- 2 files changed, 209 deletions(-) delete mode 100644 decoders/vpw/__init__.py delete mode 100644 decoders/vpw/pd.py (limited to 'decoders/vpw') diff --git a/decoders/vpw/__init__.py b/decoders/vpw/__init__.py deleted file mode 100644 index 4667efa..0000000 --- a/decoders/vpw/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -## -## This file is part of the libsigrokdecode project. -## -## Copyright (C) 2016 Anthony Symons -## -## 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, write to the Free Software -## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -## - -''' -VPW decoder, Decode GM VPW 1X and 4X Vehicle Bus -''' - -from .pd import Decoder diff --git a/decoders/vpw/pd.py b/decoders/vpw/pd.py deleted file mode 100644 index a1dd8ec..0000000 --- a/decoders/vpw/pd.py +++ /dev/null @@ -1,184 +0,0 @@ -## -## This file is part of the libsigrokdecode project. -## -## Copyright (C) 2016 Anthony Symons -## -## 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, write to the Free Software -## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -## - -import sigrokdecode as srd - -class SamplerateError(Exception): - pass - -def timeuf(t): - return int (t * 1000.0 * 1000.0) - -def normalize_time(t): - if t >= 1.0: - return '%d s' % t - elif t >= 0.001: - return '%d ms' % (t * 1000.0) - elif t >= 0.000001: - return '%d μs' % (t * 1000.0 * 1000.0) - elif t >= 0.000000001: - return '%d ns' % (t * 1000.0 * 1000.0 * 1000.0) - else: - return '%f' % t - -class Decoder(srd.Decoder): - api_version = 2 - id = 'vpw' - name = 'VPW' - longname = 'J1850 VPW Decoder' - desc = 'Decode J1850 VPW 1x and 4x' - license = 'gplv2+' - inputs = ['logic'] - outputs = ['timing'] - channels = ( - {'id': 'data', 'name': 'Data', 'desc': 'Data line'}, - ) - annotations = ( - ('time', 'Time'), - ('raw', 'Raw'), - ('sof', 'SOF'), - ('ifs', 'EOF/IFS'), - ('data', 'Data'), - ('packet', 'Packet'), - ) - annotation_rows = ( - ('packet', 'Packet', (5,)), - ('byte', 'Byte', (4,)), - ('raw', 'Raw', (1,2,3,)), - ('time', 'Time', (0,)), - ) - - def __init__(self, **kwargs): - self.state = 'IDLE' - self.samplerate = None - self.oldpin = None - self.last_samplenum = None - self.byte = 0 # the byte offset in the packet - self.mode = 0 # for by packet decode - self.data = 0 # the current byte - self.datastart = 0 # sample number this byte started at - self.csa = 0 # track the last byte seperately to retrospectively add the CS marker - self.csb = 0 - self.count = 0 # which bit number we are up to - self.active = 0 # which logic level is considered active - - # vpw timings. ideal, min and max tollerances. - # From SAE J1850 1995 rev section 23.406 - - self.sof = 200 - self.sofl = 164 - self.sofh = 245 # 240 by the spec, 245 so a 60us 4x sample will pass - self.long = 128 - self.longl = 97 - self.longh = 170 # 164 by the spec but 170 for low sample rate tolerance. - self.short = 64 - self.shortl = 24 # 35 by the spec, 24 to allow down to 6us as measured in practice for 4x @ 1mhz sampling - self.shorth = 97 - self.ifs = 240 - self.spd = 1 # set to 4 when a 4x SOF is detected (VPW high speed frame) - - def handle_bit(self, b): - self.data |= (b << 7-self.count) # MSB-first - self.put(self.last_samplenum, self.samplenum, self.out_ann, [1, ["%d" % b]]) - if self.count == 0: - self.datastart = self.last_samplenum - if self.count == 7: - self.csa = self.datastart # for CS - self.csb = self.samplenum # for CS - self.put(self.datastart, self.samplenum, self.out_ann, [4, ["%02X" % self.data]]) - # add protocol parsing here - if self.byte == 0: - self.put(self.datastart, self.samplenum, self.out_ann, [5, ['Priority','Prio','P']]) - elif self.byte == 1: - self.put(self.datastart, self.samplenum, self.out_ann, [5, ['Destination','Dest','D']]) - elif self.byte == 2: - self.put(self.datastart, self.samplenum, self.out_ann, [5, ['Source','Src','S']]) - elif self.byte == 3: - self.put(self.datastart, self.samplenum, self.out_ann, [5, ['Mode','M']]) - self.mode=self.data - elif self.mode == 1 and self.byte == 4: # mode 1 payload - self.put(self.datastart, self.samplenum, self.out_ann, [5, ['Pid','P']]) - - # prepare for next byte - self.count = -1 - self.data = 0 - self.byte = self.byte + 1 # track packet offset - self.count = self.count + 1 - - def metadata(self, key, value): - if key == srd.SRD_CONF_SAMPLERATE: - self.samplerate = value - - def start(self): - self.out_ann = self.register(srd.OUTPUT_ANN) - - def decode(self, ss, es, data): - if not self.samplerate: - raise SamplerateError('Cannot decode without samplerate.') - - for (self.samplenum, (pin,)) in data: - # Ignore identical samples early on (for performance reasons). - if self.oldpin == pin: - continue - - if self.oldpin is None: - self.oldpin = pin - self.last_samplenum = self.samplenum - continue - - if self.oldpin != pin: - samples = self.samplenum - self.last_samplenum - txt=normalize_time(samples / self.samplerate) - self.put(self.last_samplenum, self.samplenum, self.out_ann, [0, [txt]]) - t=timeuf(samples / self.samplerate) - if self.state == 'IDLE': # detect and set speed from the size of sof - if pin==self.active and t in range(self.sofl , self.sofh): - self.put(self.last_samplenum, self.samplenum, self.out_ann, [1, ['1X SOF', 'S1', 'S']]) - self.spd = 1 - self.data = 0 - self.count = 0 - self.state = 'DATA' - elif pin==self.active and t in range(int(self.sofl/4) , int(self.sofh/4)): - self.put(self.last_samplenum, self.samplenum, self.out_ann, [1, ['4X SOF', 'S4', '4']]) - self.spd = 4 - self.data = 0 - self.count = 0 - self.state = 'DATA' - - elif self.state == 'DATA': - if t >= int(self.ifs/self.spd): - self.state = 'IDLE' - self.put(self.last_samplenum, self.samplenum, self.out_ann, [1, ["EOF/IFS", "E"]]) # EOF=239-280 IFS=281+ - self.put(self.csa, self.csb, self.out_ann, [5, ['Checksum','CS','C']]) # retrospective print of CS - self.byte = 0 # reset packet offset - elif t in range(int(self.shortl/self.spd), int(self.shorth/self.spd)): - if pin==self.active: - self.handle_bit(1) - else: - self.handle_bit(0) - elif t in range(int(self.longl/self.spd), int(self.longh/self.spd)): - if pin==self.active: - self.handle_bit(0) - else: - self.handle_bit(1) - - # Store data for next round. - self.last_samplenum = self.samplenum - self.oldpin = pin -- cgit v1.2.3-70-g09d2