]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/seven_segment/pd.py
seven_segment: Initial commit.
[libsigrokdecode.git] / decoders / seven_segment / pd.py
diff --git a/decoders/seven_segment/pd.py b/decoders/seven_segment/pd.py
new file mode 100644 (file)
index 0000000..26d1d83
--- /dev/null
@@ -0,0 +1,138 @@
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2019 Benedikt Otto <benedikt_o@web.de>
+##
+## 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, see <http://www.gnu.org/licenses/>.
+##
+
+import sigrokdecode as srd
+
+class ChannelError(Exception):
+    pass
+
+digits = {
+    (0, 0, 0, 0, 0, 0, 0): ' ',
+    (1, 1, 1, 1, 1, 1, 0): '0',
+    (0, 1, 1, 0, 0, 0, 0): '1',
+    (1, 1, 0, 1, 1, 0, 1): '2',
+    (1, 1, 1, 1, 0, 0, 1): '3',
+    (0, 1, 1, 0, 0, 1, 1): '4',
+    (1, 0, 1, 1, 0, 1, 1): '5',
+    (1, 0, 1, 1, 1, 1, 1): '6',
+    (1, 1, 1, 0, 0, 0, 0): '7',
+    (1, 1, 1, 1, 1, 1, 1): '8',
+    (1, 1, 1, 1, 0, 1, 1): '9',
+    (1, 1, 1, 0, 1, 1, 1): 'A',
+    (0, 0, 1, 1, 1, 1, 1): 'B',
+    (1, 0, 0, 1, 1, 1, 0): 'C',
+    (0, 1, 1, 1, 1, 0, 1): 'D',
+    (1, 0, 0, 1, 1, 1, 1): 'E',
+    (1, 0, 0, 0, 1, 1, 1): 'F',
+}
+
+class Decoder(srd.Decoder):
+    api_version = 3
+    id = 'seven_segment'
+    name = '7-segment'
+    longname = '7-segment display'
+    desc = '7-segment display protocol.'
+    license = 'gplv2+'
+    inputs = ['logic']
+    outputs = []
+    tags = ['Display']
+    channels = (
+        {'id': 'a', 'name': 'A', 'desc': 'Segment A'},
+        {'id': 'b', 'name': 'B', 'desc': 'Segment B'},
+        {'id': 'c', 'name': 'C', 'desc': 'Segment C'},
+        {'id': 'd', 'name': 'D', 'desc': 'Segment D'},
+        {'id': 'e', 'name': 'E', 'desc': 'Segment E'},
+        {'id': 'f', 'name': 'F', 'desc': 'Segment F'},
+        {'id': 'g', 'name': 'G', 'desc': 'Segment G'},
+    )
+    optional_channels = (
+        {'id': 'dp', 'name': 'DP', 'desc': 'Decimal point'},
+    )
+    options = (
+        {'id': 'polarity', 'desc': 'Expected polarity',
+            'default': 'common-cathode', 'values': ('common-cathode', 'common-anode')},
+    )
+    annotations = (
+        ('decoded-digit', 'Decoded digit'),
+    )
+    annotation_rows = (
+        ('decoded-digits', 'Decoded digits', (0,)),
+    )
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        pass
+
+    def start(self):
+        self.out_ann = self.register(srd.OUTPUT_ANN)
+
+    def putb(self, ss_block, es_block, data):
+        self.put(ss_block, es_block, self.out_ann, data)
+
+    def pins_to_hex(self, pins):
+        if pins in digits:
+            return digits[pins]
+        else:
+            return None
+
+    def decode(self):
+        oldpins = self.wait()
+
+        # Check if at least the 7 signals are present.
+        if False in [p in (0, 1) for p in oldpins[:7]]:
+            raise ChannelError('7 or 8 pins have to be present.')
+
+        lastpos = self.samplenum
+
+        self.have_dp = self.has_channel(7)
+
+        conditions = [{0: 'e'}, {1: 'e'}, {2: 'e'}, {3: 'e'}, {4: 'e'}, {5: 'e'}, {6: 'e'}]
+
+        if self.have_dp:
+            conditions.append({7: 'e'})
+
+        while True:
+            # Wait for any change.
+            pins = self.wait(conditions)
+
+            if self.options['polarity'] == 'common-anode':
+                # Invert all data lines if a common anode display is used.
+                if self.have_dp:
+                    oldpins = tuple((1 - state for state in oldpins))
+                else:
+                    oldpins = tuple((1 - state for state in oldpins[:7]))
+
+            # Convert to character string.
+            digit = self.pins_to_hex(oldpins[:7])
+
+            if digit is not None:
+                dp = oldpins[7]
+
+                # Check if decimal point is present and active.
+                if self.have_dp:
+                    if dp == 1:
+                        digit = digit + '.'
+
+                self.putb(lastpos, self.samplenum, [0, [digit]])
+
+            lastpos = self.samplenum
+
+            oldpins = pins