summaryrefslogtreecommitdiff
path: root/decoders
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2020-05-02 15:49:05 +0200
committerGerhard Sittig <gerhard.sittig@gmx.net>2020-07-07 20:42:42 +0200
commit41e0dd7ae3d5587011ea7f37f5dc83b232fa5373 (patch)
tree2956bffec72f7a1b8cc214ba60f0d4303ab03065 /decoders
parent3bd25dea9d260d738f2dfaef697d6455545cde62 (diff)
downloadlibsigrokdecode-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)