Hi,

I've put together a basic Wiegand decoder that extracts bit streams from
wiegand signals.  It stops at the binary level and doesn't extract facility
codes/identity numbers etc.  This is on the list of possible future
decoders at
https://sigrok.org/wiki/Protocol_decoders#Possible_candidates_for_future_protocol_decoders

Decoding the attached wiegand.srzip should result in two decodes of the 36
bit value 0010001010011001000000100100010000

Let me know if you need anything more.

-- 
Sean Burford <sburf...@google.com>

Attachment: wiegand.srzip
Description: Binary data

From deb37953d464c13eda8e4b0e866228ac03ee1b9c Mon Sep 17 00:00:00 2001
From: Sean Burford <sburf...@google.com>
Date: Wed, 27 Apr 2016 10:22:39 +1000
Subject: [PATCH 1/1] Add wiegand decoder.

---
 decoders/wiegand/__init__.py |  29 +++++++++
 decoders/wiegand/pd.py       | 140 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 decoders/wiegand/__init__.py
 create mode 100644 decoders/wiegand/pd.py

diff --git a/decoders/wiegand/__init__.py b/decoders/wiegand/__init__.py
new file mode 100644
index 0000000..20f51f8
--- /dev/null
+++ b/decoders/wiegand/__init__.py
@@ -0,0 +1,29 @@
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2016 Sean Burford <sburf...@google.com>
+##
+## 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
+##
+
+'''
+The Wiegand interface is a de facto wiring standard commonly used to connect
+a card swipe mechanism to the rest of an electronic entry system.
+
+Details:
+https://en.wikipedia.org/wiki/Wiegand_interface
+'''
+
+from .pd import Decoder
diff --git a/decoders/wiegand/pd.py b/decoders/wiegand/pd.py
new file mode 100644
index 0000000..fc49e0b
--- /dev/null
+++ b/decoders/wiegand/pd.py
@@ -0,0 +1,140 @@
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2016 Sean Burford <sburf...@google.com>
+##
+## 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 Decoder(srd.Decoder):
+    api_version = 2
+    id = 'wiegand'
+    name = 'Wiegand'
+    longname = 'Wiegand Interface'
+    desc = 'Wiegand Interface for electronic entry systems.'
+    license = 'gplv2+'
+    inputs = ['logic']
+    outputs = ['wiegand']
+    channels = (
+        {'id': 'd0', 'name': 'D0', 'desc': 'Data 0 line'},
+        {'id': 'd1', 'name': 'D1', 'desc': 'Data 1 line'},
+    )
+    options = (
+        {'id': 'active', 'desc': 'Data lines active level',
+         'default': 'low', 'values': ('low', 'high')},
+        {'id': 'bitwidth_ms', 'desc': 'Single bit width in milliseconds',
+         'default': '4', 'values': ('1', '2', '4', '8', '16', '32')},
+    )
+    annotations = (
+        ('bits', 'Bits'),
+        ('state', 'State'),
+    )
+    annotation_rows = (
+        ('bits', 'Binary Value', (0,)),
+        ('state', 'Stream State', (1,)),
+    )
+    binary = ()
+
+    def __init__(self, **kwargs):
+        super(Decoder, self).__init__(**kwargs)
+
+        self._out_annotation = None
+        self._samples_per_bit = 10
+
+        self._d0_prev = None
+        self._d1_prev = None
+
+        self._state = None
+        self._state_start = None
+
+        self._bit = None
+        self._bit_start = None
+        self._bit_end = None
+        self._bits = []
+
+    def start(self):
+        """Register output types and verify user supplied decoder values."""
+        self.out_annotation = self.register(srd.OUTPUT_ANN)
+        self._active = self.options['active'] == 'high' and 1 or 0
+        self._inactive = 1 - self._active
+
+    def metadata(self, key, value):
+        """Receive decoder metadata about the data stream."""
+        if key == srd.SRD_CONF_SAMPLERATE:
+            ms_per_sample = 1000 * (1.0 / value)
+            ms_per_bit = float(self.options['bitwidth_ms'])
+            self._samples_per_bit = int(max(1, int(ms_per_bit / ms_per_sample)))
+
+    def _update_state(self, samplenum, state, bit=None):
+        """Update state and bit values when they change."""
+        if self._bit is not None:
+            self._bits.append(self._bit)
+            self.put(self._bit_start, samplenum, self.out_annotation,
+                     [0, [str(self._bit),]])
+        self._bit = bit
+        self._bit_start = samplenum
+        if bit is not None:
+            # Set a timeout so that the final bit ends.
+            self._bit_end = samplenum + self._samples_per_bit
+        else:
+            self._bit_end = None
+
+        if state != self._state:
+            ann = None
+            if self._state == 'data':
+                accum_bits = ''.join(str(x) for x in self._bits)
+                ann = [1, ['%d bits %s' % (len(self._bits), accum_bits),
+                           '%d bits' % len(self._bits)]]
+            elif self._state == 'invalid':
+                ann = [1, [self._state]]
+            if ann:
+                self.put(self._state_start, samplenum, self.out_annotation, ann)
+            self._state_start = samplenum
+            self._state = state
+            self._bits = []
+
+    def decode(self, startsample, endsample, data):
+        """Receive and decode samples."""
+        for samplenum, (d0, d1) in data:
+            if d0 == self._d0_prev and d1 == self._d1_prev:
+                if self._bit_end and samplenum >= self._bit_end:
+                    if (d0, d1) == (self._inactive, self._inactive):
+                        self._update_state(samplenum, 'idle')
+                    else:
+                        self._update_state(samplenum, 'invalid')
+                continue
+
+            if self._state in (None, 'idle', 'data'):
+                if (d0, d1) == (self._active, self._inactive):
+                    self._update_state(samplenum, 'data', 0)
+                elif (d0, d1) == (self._inactive, self._active):
+                    self._update_state(samplenum, 'data', 1)
+                elif (d0, d1) == (self._active, self._active):
+                    self._update_state(samplenum, 'invalid')
+            elif self._state == 'invalid':
+                # Wait until we see an idle state before leaving invalid.
+                # This prevents inverted lines from being misread.
+                if (d0, d1) == (self._inactive, self._inactive):
+                    self._update_state(samplenum, 'idle')
+
+            self._d0_prev, self._d1_prev = d0, d1
+
+    def report(self):
+        return '%s: %s D0 %d D1 %d (active on %d), %d samples per bit' % (
+            self.name, self._state, self._d0_prev, self._d1_prev,
+            self._active, self._samples_per_bit)
+
-- 
2.8.0.rc3.226.g39d4020

------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to