2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2018 Steve R <steversig@virginmedia.com>
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.
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.
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/>.
20 import sigrokdecode as srd
21 from common.srdhelper import bcd2int
23 class Decoder(srd.Decoder):
26 name = 'OOK visualisation'
27 longname = 'On-off keying visualisation'
28 desc = 'OOK visualisation in various formats.'
36 ('ref_field', 'Ref field'),
38 ('ref_level2', 'Ref L2'),
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,)),
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',
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')},
67 self.decoded = [] # Local cache of decoded OOK.
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']
81 self.put(self.ss, self.es, self.out_ann, data)
84 self.put(self.ss, self.es, self.out_python, data)
86 def display_level2(self, bits, line):
89 # Find the end of the preamble which could be 1010 or 1111.
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
96 char_last = char_first
99 char_last = char_second
100 for i in range(len(ook)):
101 if preamble == '1111':
102 if ook[i][2] != char_last:
106 char_last = ook[i][2]
108 if ook[i][2] != char_last:
109 char_last = ook[i][2]
114 if len(ook) >= preamble_end:
115 preamble_end += int(self.sync_offset) - 1
117 self.es = ook[preamble_end][1]
118 self.putx([line, ['Preamble', 'Pre', 'P']])
119 self.decode_pos += preamble_end
121 if len(ook) > self.decode_pos + int(self.sync_length):
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
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)
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
146 def display_all(self):
150 for i in range(len(ook)):
151 self.ookstring += ook[i][2]
152 if 'Nibble' in self.displayas:
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)
162 self.display_level2(bits, 4) # Display L2 decode.
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)]])
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]]])
186 def add_to_cache(self): # Cache the OOK so it can be used as a reference.
187 self.ookcache.append(self.decoded)
189 def decode(self, ss, es, data):
197 self.putp(data) # Send data up the stack.