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