]> sigrok.org Git - libsigrokdecode.git/blame - decoders/ook_vis/pd.py
added ook_vis
[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
116 self.ss = ook[0][0]
117 self.es = ook[preamble_end][1]
118 self.putx([line, ['Preamble', 'Pre', 'P']])
119 self.decode_pos += preamble_end
120
121 if len(ook) > self.decode_pos + int(self.sync_length):
122 self.ss = self.es
123 self.es = ook[self.decode_pos + int(self.sync_length)][1]
124 self.putx([line, ['Sync', 'Syn', 'S']])
125 self.decode_pos += int(self.sync_length) + 1
126
127 ookstring = self.ookstring[self.decode_pos:]
128 rem_nibbles = len(ookstring) // bits
129 for i in range(rem_nibbles): # Display the rest of nibbles.
130 self.ss = ook[self.decode_pos][0]
131 self.es = ook[self.decode_pos + bits - 1][1]
132 self.put_field(bits, line)
133
134 def put_field(self, numbits, line):
135 param = self.ookstring[self.decode_pos:self.decode_pos + numbits]
136 if 'rev' in self.displayas:
137 param = param[::-1] # Reversed from right.
138 if not 'E' in param: # Format if no errors.
139 if 'Hex' in self.displayas:
140 param = hex(int(param, 2))[2:]
141 elif 'BCD' in self.displayas:
142 param = bcd2int(int(param, 2))
143 self.putx([line, [str(param)]])
144 self.decode_pos += numbits
145
146 def display_all(self):
147 ookstring = ''
148 self.decode_pos = 0
149 ook = self.decoded
150 for i in range(len(ook)):
151 self.ookstring += ook[i][2]
152 if 'Nibble' in self.displayas:
153 bits = 4
154 else:
155 bits = 8
156 rem_nibbles = len(self.ookstring) // bits
157 for i in range(rem_nibbles): # Display the rest of the nibbles.
158 self.ss = ook[self.decode_pos][0]
159 self.es = ook[self.decode_pos + bits - 1][1]
160 self.put_field(bits, 2)
161
162 self.display_level2(bits, 4) # Display L2 decode.
163
164 if (self.ref != 'off' and self.ref != 'show numbers' and
165 len(self.ookcache) >= int(self.ref)): # Compare traces.
166 ref = int(self.ref) - 1
167 self.display_ref(self.trace_num, ref)
168 if len(self.ookcache) == int(self.ref): # Backfill.
169 for i in range(0, ref):
170 self.display_ref(i, ref)
171 elif self.ref == 'show numbers': # Display ref numbers.
172 self.ss = self.ookcache[self.trace_num][0][0]
173 end_sig = len(self.ookcache[self.trace_num]) - 1
174 self.es = self.ookcache[self.trace_num][end_sig][1]
175 self.putx([1, [str(self.trace_num + 1)]])
176
177 def display_ref(self, t_num, ref):
178 display_len = len(self.ookcache[ref])
179 if len(self.ookcache[t_num]) < len(self.ookcache[ref]):
180 display_len = len(self.ookcache[t_num])
181 for i in range(display_len):
182 self.ss = self.ookcache[t_num][i][0]
183 self.es = self.ookcache[t_num][i][1]
184 self.putx([1, [self.ookcache[ref][i][2]]])
185
186 def add_to_cache(self): # Cache the OOK so it can be used as a reference.
187 self.ookcache.append(self.decoded)
188
189 def decode(self, ss, es, data):
190 self.decoded = data
191 self.add_to_cache()
192 self.display_all()
193 self.ookstring = ''
194 self.trace_num += 1
195 self.ss = ss
196 self.es = es
197 self.putp(data) # Send data up the stack.