]> sigrok.org Git - libsigrokdecode.git/blob - decoders/seven_segment/pd.py
87714bbcd81483df06817f9aa374c0b31d2bd293
[libsigrokdecode.git] / decoders / seven_segment / pd.py
1 ##
2 ## This file is part of the libsigrokdecode project.
3 ##
4 ## Copyright (C) 2019 Benedikt Otto <benedikt_o@web.de>
5 ##
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
10 ##
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ## GNU General Public License for more details.
15 ##
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
18 ##
19
20 import sigrokdecode as srd
21
22 class ChannelError(Exception):
23     pass
24
25 digits = {
26     (0, 0, 0, 0, 0, 0, 0): ' ',
27     (1, 1, 1, 1, 1, 1, 0): '0',
28     (0, 1, 1, 0, 0, 0, 0): '1',
29     (1, 1, 0, 1, 1, 0, 1): '2',
30     (1, 1, 1, 1, 0, 0, 1): '3',
31     (0, 1, 1, 0, 0, 1, 1): '4',
32     (1, 0, 1, 1, 0, 1, 1): '5',
33     (1, 0, 1, 1, 1, 1, 1): '6',
34     (1, 1, 1, 0, 0, 0, 0): '7',
35     (1, 1, 1, 1, 1, 1, 1): '8',
36     (1, 1, 1, 1, 0, 1, 1): '9',
37     (1, 1, 1, 0, 1, 1, 1): 'A',
38     (0, 0, 1, 1, 1, 1, 1): 'B',
39     (1, 0, 0, 1, 1, 1, 0): 'C',
40     (0, 1, 1, 1, 1, 0, 1): 'D',
41     (1, 0, 0, 1, 1, 1, 1): 'E',
42     (1, 0, 0, 0, 1, 1, 1): 'F',
43 }
44
45 class Decoder(srd.Decoder):
46     api_version = 3
47     id = 'seven_segment'
48     name = '7-segment'
49     longname = '7-segment display'
50     desc = '7-segment display protocol.'
51     license = 'gplv2+'
52     inputs = ['logic']
53     outputs = []
54     tags = ['Display']
55     channels = (
56         {'id': 'a', 'name': 'A', 'desc': 'Segment A'},
57         {'id': 'b', 'name': 'B', 'desc': 'Segment B'},
58         {'id': 'c', 'name': 'C', 'desc': 'Segment C'},
59         {'id': 'd', 'name': 'D', 'desc': 'Segment D'},
60         {'id': 'e', 'name': 'E', 'desc': 'Segment E'},
61         {'id': 'f', 'name': 'F', 'desc': 'Segment F'},
62         {'id': 'g', 'name': 'G', 'desc': 'Segment G'},
63     )
64     optional_channels = (
65         {'id': 'dp', 'name': 'DP', 'desc': 'Decimal point'},
66     )
67     options = (
68         {'id': 'polarity', 'desc': 'Expected polarity',
69             'default': 'common-cathode', 'values': ('common-cathode', 'common-anode')},
70     )
71     annotations = (
72         ('decoded-digit', 'Decoded digit'),
73     )
74     annotation_rows = (
75         ('decoded-digits', 'Decoded digits', (0,)),
76     )
77
78     def __init__(self):
79         self.reset()
80
81     def reset(self):
82         pass
83
84     def start(self):
85         self.out_ann = self.register(srd.OUTPUT_ANN)
86
87     def putb(self, ss_block, es_block, data):
88         self.put(ss_block, es_block, self.out_ann, data)
89
90     def pins_to_hex(self, pins):
91         return digits.get(pins, None)
92
93     def decode(self):
94         oldpins = self.wait()
95
96         # Check if at least the 7 signals are present.
97         if False in [p in (0, 1) for p in oldpins[:7]]:
98             raise ChannelError('7 or 8 pins have to be present.')
99
100         lastpos = self.samplenum
101
102         self.have_dp = self.has_channel(7)
103
104         conditions = [{0: 'e'}, {1: 'e'}, {2: 'e'}, {3: 'e'}, {4: 'e'}, {5: 'e'}, {6: 'e'}]
105
106         if self.have_dp:
107             conditions.append({7: 'e'})
108
109         while True:
110             # Wait for any change.
111             pins = self.wait(conditions)
112
113             if self.options['polarity'] == 'common-anode':
114                 # Invert all data lines if a common anode display is used.
115                 if self.have_dp:
116                     oldpins = tuple((1 - state for state in oldpins))
117                 else:
118                     oldpins = tuple((1 - state for state in oldpins[:7]))
119
120             # Convert to character string.
121             digit = self.pins_to_hex(oldpins[:7])
122
123             if digit is not None:
124                 dp = oldpins[7]
125
126                 # Check if decimal point is present and active.
127                 if self.have_dp and dp == 1:
128                     digit += '.'
129
130                 self.putb(lastpos, self.samplenum, [0, [digit]])
131
132             lastpos = self.samplenum
133
134             oldpins = pins