]> sigrok.org Git - libsigrokdecode.git/blame - decoders/ook_vis/pd.py
ook_vis: Minor code simplifications.
[libsigrokdecode.git] / decoders / ook_vis / pd.py
CommitLineData
51753e22
S
1##
2## This file is part of the libsigrokdecode project.
3##
4## Copyright (C) 2018 Steve R <steversig@virginmedia.com>
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
21from common.srdhelper import bcd2int
22
23class Decoder(srd.Decoder):
24 api_version = 3
25 id = 'ook_vis'
26 name = 'OOK visualisation'
27 longname = 'On-off keying visualisation'
28 desc = 'OOK visualisation in various formats.'
29 license = 'gplv2+'
30 inputs = ['ook']
31 outputs = ['ook']
32 annotations = (
33 ('bit', 'Bit'),
34 ('ref', 'Reference'),
35 ('field', 'Field'),
36 ('ref_field', 'Ref field'),
37 ('level2', 'L2'),
38 ('ref_level2', 'Ref L2'),
39 )
40 annotation_rows = (
41 ('bits', 'Bits', (0,)),
42 ('compare', 'Compare', (1,)),
43 ('fields', 'Fields', (2,)),
44 ('ref_fields', 'Ref fields', (3,)),
45 ('level2', 'L2', (4,)),
46 ('ref_level2', 'Ref L2', (5,)),
47 )
48 options = (
49 {'id': 'displayas', 'desc': 'Display as', 'default': 'Nibble - Hex',
50 'values': ('Byte - Hex', 'Byte - Hex rev', 'Byte - BCD',
51 'Byte - BCD rev', 'Nibble - Hex', 'Nibble - Hex rev', 'Nibble - BCD',
52 'Nibble - BCD rev')},
53 {'id': 'synclen', 'desc': 'Sync length', 'default': '4',
54 'values': ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10')},
55 {'id': 'syncoffset', 'desc': 'Sync offset', 'default': '0',
56 'values': ('-4', '-3', '-2', '-1', '0', '1', '2', '3', '4')},
57 {'id': 'refsample', 'desc': 'Compare', 'default': 'off', 'values':
58 ('off', 'show numbers', '1', '2', '3', '4', '5', '6', '7', '8', '9',
59 '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
60 '21', '22', '23', '24', '25', '26', '27', '28', '29', '30')},
61 )
62
63 def __init__(self):
64 self.reset()
65
66 def reset(self):
67 self.decoded = [] # Local cache of decoded OOK.
68 self.ookstring = ''
69 self.ookcache = []
70 self.trace_num = 0
71
72 def start(self):
73 self.out_ann = self.register(srd.OUTPUT_ANN)
74 self.out_python = self.register(srd.OUTPUT_PYTHON)
75 self.displayas = self.options['displayas']
76 self.sync_length = self.options['synclen']
77 self.sync_offset = self.options['syncoffset']
78 self.ref = self.options['refsample']
79
80 def putx(self, data):
81 self.put(self.ss, self.es, self.out_ann, data)
82
83 def putp(self, data):
84 self.put(self.ss, self.es, self.out_python, data)
85
86 def display_level2(self, bits, line):
87 self.decode_pos = 0
88 ook = self.decoded
89 # Find the end of the preamble which could be 1010 or 1111.
90 if len(ook) > 1:
91 preamble_end = len(ook) + 1
92 char_first = ook[0][2]
93 char_second = ook[1][2]
94 if char_first == char_second: # 1111
95 preamble = '1111'
96 char_last = char_first
97 else:
98 preamble = '1010'
99 char_last = char_second
100 for i in range(len(ook)):
101 if preamble == '1111':
102 if ook[i][2] != char_last:
103 preamble_end = i
104 break
105 else:
106 char_last = ook[i][2]
107 else:
108 if ook[i][2] != char_last:
109 char_last = ook[i][2]
110 else:
111 preamble_end = i
112 break
113
114 if len(ook) >= preamble_end:
115 preamble_end += int(self.sync_offset) - 1
3d188680 116 self.ss, self.es = ook[0][0], ook[preamble_end][1]
51753e22
S
117 self.putx([line, ['Preamble', 'Pre', 'P']])
118 self.decode_pos += preamble_end
119
120 if len(ook) > self.decode_pos + int(self.sync_length):
121 self.ss = self.es
122 self.es = ook[self.decode_pos + int(self.sync_length)][1]
123 self.putx([line, ['Sync', 'Syn', 'S']])
124 self.decode_pos += int(self.sync_length) + 1
125
126 ookstring = self.ookstring[self.decode_pos:]
127 rem_nibbles = len(ookstring) // bits
128 for i in range(rem_nibbles): # Display the rest of nibbles.
129 self.ss = ook[self.decode_pos][0]
130 self.es = ook[self.decode_pos + bits - 1][1]
131 self.put_field(bits, line)
132
133 def put_field(self, numbits, line):
134 param = self.ookstring[self.decode_pos:self.decode_pos + numbits]
135 if 'rev' in self.displayas:
136 param = param[::-1] # Reversed from right.
137 if not 'E' in param: # Format if no errors.
138 if 'Hex' in self.displayas:
139 param = hex(int(param, 2))[2:]
140 elif 'BCD' in self.displayas:
141 param = bcd2int(int(param, 2))
142 self.putx([line, [str(param)]])
143 self.decode_pos += numbits
144
145 def display_all(self):
146 ookstring = ''
147 self.decode_pos = 0
148 ook = self.decoded
149 for i in range(len(ook)):
150 self.ookstring += ook[i][2]
3d188680 151 bits = 4 if 'Nibble' in self.displayas else 8
51753e22
S
152 rem_nibbles = len(self.ookstring) // bits
153 for i in range(rem_nibbles): # Display the rest of the nibbles.
154 self.ss = ook[self.decode_pos][0]
155 self.es = ook[self.decode_pos + bits - 1][1]
156 self.put_field(bits, 2)
157
158 self.display_level2(bits, 4) # Display L2 decode.
159
160 if (self.ref != 'off' and self.ref != 'show numbers' and
161 len(self.ookcache) >= int(self.ref)): # Compare traces.
162 ref = int(self.ref) - 1
163 self.display_ref(self.trace_num, ref)
164 if len(self.ookcache) == int(self.ref): # Backfill.
165 for i in range(0, ref):
166 self.display_ref(i, ref)
167 elif self.ref == 'show numbers': # Display ref numbers.
168 self.ss = self.ookcache[self.trace_num][0][0]
169 end_sig = len(self.ookcache[self.trace_num]) - 1
170 self.es = self.ookcache[self.trace_num][end_sig][1]
171 self.putx([1, [str(self.trace_num + 1)]])
172
173 def display_ref(self, t_num, ref):
174 display_len = len(self.ookcache[ref])
175 if len(self.ookcache[t_num]) < len(self.ookcache[ref]):
176 display_len = len(self.ookcache[t_num])
177 for i in range(display_len):
178 self.ss = self.ookcache[t_num][i][0]
179 self.es = self.ookcache[t_num][i][1]
180 self.putx([1, [self.ookcache[ref][i][2]]])
181
182 def add_to_cache(self): # Cache the OOK so it can be used as a reference.
183 self.ookcache.append(self.decoded)
184
185 def decode(self, ss, es, data):
186 self.decoded = data
187 self.add_to_cache()
188 self.display_all()
189 self.ookstring = ''
190 self.trace_num += 1
191 self.ss = ss
192 self.es = es
193 self.putp(data) # Send data up the stack.