]> sigrok.org Git - libsigrokdecode.git/blob - decoders/seven_segment/pd.py
d090cfffc5c546328820146f150e2d41cba47d44
[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     (0, 1, 0, 0, 0, 1, 0): '"',
28     (1, 1, 0, 1, 1, 1, 1): "&",
29     (0, 0, 0, 0, 0, 1, 0): "'",
30     (0, 1, 0, 0, 0, 0, 0): "'",
31     (0, 0, 1, 1, 0, 0, 0): ',',
32     (0, 0, 0, 0, 0, 0, 1): '-',
33     (0, 0, 0, 0, 1, 0, 0): '.',
34     (1, 1, 1, 1, 1, 1, 0): '0',
35     (0, 1, 1, 0, 0, 0, 0): '1',
36     (1, 1, 0, 1, 1, 0, 1): '2',
37     (1, 1, 1, 1, 0, 0, 1): '3',
38     (0, 1, 1, 0, 0, 1, 1): '4',
39     (1, 0, 1, 1, 0, 1, 1): '5',
40     (1, 0, 1, 1, 1, 1, 1): '6',
41     (1, 1, 1, 0, 0, 1, 0): '7',
42     (1, 1, 1, 0, 0, 0, 0): '7',
43     (1, 1, 1, 1, 1, 1, 1): '8',
44     (1, 1, 1, 1, 0, 1, 1): '9',
45     (1, 0, 0, 0, 0, 0, 1): '=',
46     (0, 0, 0, 1, 0, 0, 1): '=',
47     (1, 1, 0, 0, 1, 0, 1): '?',
48     (1, 1, 1, 0, 1, 1, 1): 'A',
49     (1, 1, 1, 1, 1, 0, 1): 'a',
50     (0, 0, 1, 1, 1, 1, 1): 'b',
51     (1, 0, 0, 1, 1, 1, 0): 'C',
52     (0, 0, 0, 1, 1, 0, 1): 'c',
53     (0, 1, 1, 1, 1, 0, 1): 'd',
54     (1, 0, 0, 1, 1, 1, 1): 'E',
55     (1, 0, 0, 0, 1, 1, 1): 'F',
56     (1, 0, 1, 1, 1, 1, 0): 'G',
57     (0, 1, 1, 0, 1, 1, 1): 'H',
58     (0, 0, 1, 0, 1, 1, 1): 'h',
59     (0, 0, 0, 0, 1, 1, 0): 'I',
60     (1, 0, 0, 0, 1, 0, 0): 'i',
61     (0, 0, 1, 0, 0, 0, 0): 'i',
62     (0, 1, 1, 1, 1, 0, 0): 'J',
63     (0, 1, 1, 1, 0, 0, 0): 'J',
64     (1, 0, 1, 1, 0, 0, 0): 'j',
65     (1, 0, 1, 0, 1, 1, 1): 'K',
66     (0, 0 ,0, 1, 1, 1, 0): 'L',
67     (1, 0, 1, 0, 1, 0, 0): 'M',
68     (1, 0, 1, 0, 1, 0, 1): 'M',
69     (1, 1, 1, 0, 1, 1, 0): 'N',
70     (0, 0, 1, 0, 1, 0, 1): 'n',
71     (0, 0, 1, 1, 1, 0, 1): 'o',
72     (1, 1, 0, 0, 1, 1, 1): 'p',
73     (1, 1, 1, 0, 0, 1, 1): 'q',
74     (1, 1, 0, 0, 1, 1, 0): 'R',
75     (0, 0, 0, 0, 1, 0, 1): 'r',
76     (0, 0, 0, 1, 1, 1, 1): 't',
77     (0, 0, 1, 1, 1, 0, 0): 'u',
78     (0, 1, 0, 1, 0, 1, 0): 'V',
79     (0, 1, 0, 0, 1, 1, 1): 'V',
80     (0, 1, 1, 1, 1, 1, 0): 'V',
81     (0, 1, 0, 0, 0, 1, 1): 'v',
82     (0, 1, 0, 1, 0, 1, 1): 'W',
83     (0, 0, 1, 0, 1, 0, 0): 'x',
84     (0, 1, 1, 1, 0, 1, 1): 'y',
85     (1, 1, 0, 1, 1, 0, 0): 'Z',
86     (1, 1, 0, 0, 0, 1, 0): '^',
87     (0, 0, 0, 1, 0, 0, 0): '_',
88 }
89
90 class Decoder(srd.Decoder):
91     api_version = 3
92     id = 'seven_segment'
93     name = '7-segment'
94     longname = '7-segment display'
95     desc = '7-segment display protocol.'
96     license = 'gplv2+'
97     inputs = ['logic']
98     outputs = []
99     tags = ['Display']
100     channels = (
101         {'id': 'a', 'name': 'A', 'desc': 'Segment A'},
102         {'id': 'b', 'name': 'B', 'desc': 'Segment B'},
103         {'id': 'c', 'name': 'C', 'desc': 'Segment C'},
104         {'id': 'd', 'name': 'D', 'desc': 'Segment D'},
105         {'id': 'e', 'name': 'E', 'desc': 'Segment E'},
106         {'id': 'f', 'name': 'F', 'desc': 'Segment F'},
107         {'id': 'g', 'name': 'G', 'desc': 'Segment G'},
108     )
109     optional_channels = (
110         {'id': 'dp', 'name': 'DP', 'desc': 'Decimal point'},
111     )
112     options = (
113         {'id': 'polarity', 'desc': 'Expected polarity',
114             'default': 'common-cathode', 'values': ('common-cathode', 'common-anode')},
115         {'id': 'show_unknown', 'desc': 'Display Unknown characters as #',
116             'default': 'no', 'values': ('yes', 'no')},
117     )
118     annotations = (
119         ('decoded-digit', 'Decoded digit'),
120     )
121     annotation_rows = (
122         ('decoded-digits', 'Decoded digits', (0,)),
123     )
124
125     def __init__(self):
126         self.reset()
127
128     def reset(self):
129         pass
130
131     def start(self):
132         self.out_ann = self.register(srd.OUTPUT_ANN)
133
134     def putb(self, ss_block, es_block, data):
135         self.put(ss_block, es_block, self.out_ann, data)
136
137     def pins_to_hex(self, pins):
138         return digits.get(pins, None)
139
140     def decode(self):
141         oldpins = self.wait()
142
143         # Check if at least the 7 signals are present.
144         if False in [p in (0, 1) for p in oldpins[:7]]:
145             raise ChannelError('7 or 8 pins have to be present.')
146
147         lastpos = self.samplenum
148
149         self.have_dp = self.has_channel(7)
150
151         conditions = [{0: 'e'}, {1: 'e'}, {2: 'e'}, {3: 'e'}, {4: 'e'}, {5: 'e'}, {6: 'e'}]
152
153         if self.have_dp:
154             conditions.append({7: 'e'})
155
156         while True:
157             # Wait for any change.
158             pins = self.wait(conditions)
159
160             if self.options['polarity'] == 'common-anode':
161                 # Invert all data lines if a common anode display is used.
162                 if self.have_dp:
163                     oldpins = tuple((1 - state for state in oldpins))
164                 else:
165                     oldpins = tuple((1 - state for state in oldpins[:7]))
166
167             # Convert to character string.
168             digit = self.pins_to_hex(oldpins[:7])
169
170             if digit is None and self.options['show_unknown'] == 'yes':
171                 digit = '#'
172
173             if digit is not None:
174                 dp = oldpins[7]
175
176                 # Check if decimal point is present and active.
177                 if self.have_dp and dp == 1:
178                     digit += '.'
179
180                 self.putb(lastpos, self.samplenum, [0, [digit]])
181
182             lastpos = self.samplenum
183
184             oldpins = pins