Hi everyone,

Measuring the simple timing of a pulse edge is the kind of thing I'd
usually just do some quick scripting for, but I figured it's nice to
be able to look at the data directly in pulseview as well so I wrote a
very simple encoder.

Here's a shot of pulseview with two of these decoders loaded:
http://i.imgur.com/ZfsZ2pg.png

Can measure across high/low/edge-to-edge/falling-to-falling or
rising-to-rising.

I've attached a patch. Happy to change/cleanup it in any way if
necessary, or be told that this isn't the right approach for this kind
of thing.

I haven't written any tests, but I can easily make some from existing
dumps if it's useful to have them.


Angus
>From 057317c216b1d8116b57a31db19cf01a1aaf8f89 Mon Sep 17 00:00:00 2001
From: Angus Gratton <[email protected]>
Date: Wed, 29 Oct 2014 09:19:38 +1100
Subject: [PATCH] pulsewidth: Add a simple decoder for measuring timing of
 pulses.

Can measure duration of an edge, or time between edge transitions
---
 decoders/pulsewidth/__init__.py |  25 +++++++++
 decoders/pulsewidth/pd.py       | 115 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100644 decoders/pulsewidth/__init__.py
 create mode 100644 decoders/pulsewidth/pd.py

diff --git a/decoders/pulsewidth/__init__.py b/decoders/pulsewidth/__init__.py
new file mode 100644
index 0000000..0238108
--- /dev/null
+++ b/decoders/pulsewidth/__init__.py
@@ -0,0 +1,25 @@
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2014 Angus Gratton <[email protected]>
+##
+## 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
+##
+
+'''
+Simple decoder of pulse width times (either duration of an edge, or time between edge transitions.)
+'''
+
+from .pd import Decoder
diff --git a/decoders/pulsewidth/pd.py b/decoders/pulsewidth/pd.py
new file mode 100644
index 0000000..a08f3e5
--- /dev/null
+++ b/decoders/pulsewidth/pd.py
@@ -0,0 +1,115 @@
+## encoding: utf-8
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2014 Angus Gratton <[email protected]>
+##
+## 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
+import re
+
+'''
+OUTPUT_PYTHON format:
+
+Packet:
+[<width>] (seconds of pulse width, floating point)
+'''
+
+class Decoder(srd.Decoder):
+    api_version = 2
+    id = 'pulsewidth'
+    name = 'Pulse Width'
+    longname = 'Pulse Width'
+    desc = 'Simple measurement of pulse durations.'
+    license = 'gplv2+'
+    inputs = ['logic']
+    outputs = ['pulsewidth']
+    channels = (
+        {'id': 'pulse', 'name': 'Pulse', 'desc': 'Data pulse to measure'},
+    )
+    options = (
+        {'id': 'pulse_type',
+         'desc': 'Pulse type to measure',
+         'default': 'low', 'values': ('low', 'high', 'edge_to_edge', 'falling_to_falling', 'rising_to_rising')},
+    )
+    annotations = (
+        ('low', 'LOW'),
+        ('high', 'HIGH'),
+    )
+
+    def __init__(self, **kwargs):
+        self.last_pulse = -1
+        self.samplerate = None
+        self.start_sample = None
+        self.start_pol = -1
+        self.last_sample = None
+
+    def start(self):
+        self.out_ann = self.register(srd.OUTPUT_ANN)
+        self.out_python = self.register(srd.OUTPUT_PYTHON)
+
+    def metadata(self, key, value):
+        if key == srd.SRD_CONF_SAMPLERATE:
+            self.samplerate = value
+
+    def decode(self, ss, es, data):
+        if self.samplerate is None:
+            raise Exception('Cannot decode without samplerate.')
+        pulse_type = self.options['pulse_type']
+        for (samplenum, (pulse,)) in data:
+            if self.start_sample is not None:
+                # currently measuring a pulse
+                is_end = {
+                    'low' : pulse == 1,
+                    'high' : pulse == 0,
+                    'edge_to_edge' : pulse != self.last_pulse,
+                    'falling_to_falling' : pulse == 0 and self.last_pulse == 1,
+                    'rising_to_rising' : pulse == 1 and self.last_pulse == 0 }[pulse_type]
+                if is_end:
+                    self.put_pulse(self.start_sample, self.last_sample)
+                    self.start_sample = None
+                else:
+                    self.last_sample = samplenum
+            if self.start_sample is None:
+                # not currently measuring a pulse
+                is_start = {
+                    'low'  : pulse == 0,
+                    'high' : pulse == 1,
+                    'edge_to_edge' : pulse != self.last_pulse,
+                    'falling_to_falling' : pulse == 0 and self.last_pulse == 1,
+                    'rising_to_rising' : pulse ==1 and self.last_pulse == 0 }[pulse_type]
+                if is_start:
+                    self.start_sample = samplenum
+                    self.start_pol = pulse
+                    self.last_sample = samplenum
+            self.last_pulse = pulse
+
+    def put_pulse(self, start, end):
+        start_ts = float(start) / self.samplerate
+        end_ts = float(end) / self.samplerate
+        delta = end_ts - start_ts
+        if delta <= 1e-6:
+            delta_s = u"%.1fns" % (delta * 1e9)
+        elif delta <= 1e-3:
+            delta_s = u"%.1fμs" % (delta * 1e6)
+        elif delta <= 1:
+            delta_s = u"%.1fms" % (delta * 1e3)
+        else:
+            delta_s = u"%.1s" % (delta)
+        # self.start_pol 0,1 maps to annotation 0,1 for annotating lows/highs differently
+        self.put(start, end, self.out_ann, [self.start_pol, [delta_s]])
+        self.put(start, end, self.out_python, [delta])
-- 
2.1.0

------------------------------------------------------------------------------
_______________________________________________
sigrok-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to