diff options
author | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-05-02 15:49:05 +0200 |
---|---|---|
committer | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-07-07 20:42:42 +0200 |
commit | 41e0dd7ae3d5587011ea7f37f5dc83b232fa5373 (patch) | |
tree | 2956bffec72f7a1b8cc214ba60f0d4303ab03065 /decoders | |
parent | 3bd25dea9d260d738f2dfaef697d6455545cde62 (diff) | |
download | libsigrokdecode-41e0dd7ae3d5587011ea7f37f5dc83b232fa5373.tar.gz libsigrokdecode-41e0dd7ae3d5587011ea7f37f5dc83b232fa5373.zip |
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 <dpriestley92@hotmail.com>
Diffstat (limited to 'decoders')
-rw-r--r-- | decoders/sae_j1850_vpw/__init__.py (renamed from decoders/vpw/__init__.py) | 5 | ||||
-rw-r--r-- | decoders/sae_j1850_vpw/pd.py (renamed from decoders/vpw/pd.py) | 145 |
2 files changed, 71 insertions, 79 deletions
diff --git a/decoders/vpw/__init__.py b/decoders/sae_j1850_vpw/__init__.py index 4667efa..6894bfd 100644 --- a/decoders/vpw/__init__.py +++ b/decoders/sae_j1850_vpw/__init__.py @@ -14,12 +14,11 @@ ## 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 +## along with this program; if not, see <http://www.gnu.org/licenses/>. ## ''' -VPW decoder, Decode GM VPW 1X and 4X Vehicle Bus +SAE J1850 Variable Pulse Width decoder. Decode GM VPW 1X and 4X Vehicle Bus. ''' from .pd import Decoder diff --git a/decoders/vpw/pd.py b/decoders/sae_j1850_vpw/pd.py index a1dd8ec..8faba64 100644 --- a/decoders/vpw/pd.py +++ b/decoders/sae_j1850_vpw/pd.py @@ -14,8 +14,7 @@ ## 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 +## along with this program; if not, see <http://www.gnu.org/licenses/>. ## import sigrokdecode as srd @@ -39,14 +38,15 @@ def normalize_time(t): 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' + api_version = 3 + id = 'sae_j1850_vpw' + name = 'SAE J1850 VPW' + longname = 'SAE J1850 VPW.' + desc = 'SAE J1850 Variable Pulse Width 1x and 4x.' license = 'gplv2+' inputs = ['logic'] - outputs = ['timing'] + outputs = [] + tags = ['Automotive'] channels = ( {'id': 'data', 'name': 'Data', 'desc': 'Data line'}, ) @@ -59,29 +59,30 @@ class Decoder(srd.Decoder): ('packet', 'Packet'), ) annotation_rows = ( - ('packet', 'Packet', (5,)), - ('byte', 'Byte', (4,)), - ('raw', 'Raw', (1,2,3,)), - ('time', 'Time', (0,)), + ('packets', 'Packets', (5,)), + ('bytes', 'Bytes', (4,)), + ('raws', 'Raws', (1,2,3,)), + ('times', 'Times', (0,)), ) - def __init__(self, **kwargs): + def __init__(self): + self.reset() + + def reset(self): 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.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. + + # 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 @@ -93,12 +94,12 @@ class Decoder(srd.Decoder): 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): + + def handle_bit(self, ss, es, b): self.data |= (b << 7-self.count) # MSB-first - self.put(self.last_samplenum, self.samplenum, self.out_ann, [1, ["%d" % b]]) + self.put(ss, es, self.out_ann, [1, ["%d" % b]]) if self.count == 0: - self.datastart = self.last_samplenum + self.datastart = ss if self.count == 7: self.csa = self.datastart # for CS self.csb = self.samplenum # for CS @@ -112,16 +113,16 @@ class Decoder(srd.Decoder): 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 + 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 @@ -129,56 +130,48 @@ class Decoder(srd.Decoder): def start(self): self.out_ann = self.register(srd.OUTPUT_ANN) - def decode(self, ss, es, data): + def decode(self): 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 + self.wait({0: 'e'}) + es = self.samplenum + while True: + ss = es + pin, = self.wait({0: 'e'}) + es = self.samplenum + + samples = es - ss + txt = normalize_time(samples / self.samplerate) + self.put(ss, es, 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(ss, es, 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(ss, es, 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(ss, es, 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(ss, es, 1) + else: + self.handle_bit(ss, es, 0) + elif t in range(int(self.longl / self.spd), int(self.longh / self.spd)): + if pin == self.active: + self.handle_bit(ss, es, 0) + else: + self.handle_bit(ss, es, 1) |