]> sigrok.org Git - libsigrokdecode.git/blame - decoders/seven_segment/pd.py
seven_segment: Initial commit.
[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
25digits = {
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
45class 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 if pins in digits:
92 return digits[pins]
93 else:
94 return None
95
96 def decode(self):
97 oldpins = self.wait()
98
99 # Check if at least the 7 signals are present.
100 if False in [p in (0, 1) for p in oldpins[:7]]:
101 raise ChannelError('7 or 8 pins have to be present.')
102
103 lastpos = self.samplenum
104
105 self.have_dp = self.has_channel(7)
106
107 conditions = [{0: 'e'}, {1: 'e'}, {2: 'e'}, {3: 'e'}, {4: 'e'}, {5: 'e'}, {6: 'e'}]
108
109 if self.have_dp:
110 conditions.append({7: 'e'})
111
112 while True:
113 # Wait for any change.
114 pins = self.wait(conditions)
115
116 if self.options['polarity'] == 'common-anode':
117 # Invert all data lines if a common anode display is used.
118 if self.have_dp:
119 oldpins = tuple((1 - state for state in oldpins))
120 else:
121 oldpins = tuple((1 - state for state in oldpins[:7]))
122
123 # Convert to character string.
124 digit = self.pins_to_hex(oldpins[:7])
125
126 if digit is not None:
127 dp = oldpins[7]
128
129 # Check if decimal point is present and active.
130 if self.have_dp:
131 if dp == 1:
132 digit = digit + '.'
133
134 self.putb(lastpos, self.samplenum, [0, [digit]])
135
136 lastpos = self.samplenum
137
138 oldpins = pins