]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | import sigrokdecode as srd | |
21 | from common.srdhelper import bcd2int | |
22 | ||
23 | class 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'] | |
d6d8a8a4 | 32 | tags = ['Encoding'] |
51753e22 S |
33 | annotations = ( |
34 | ('bit', 'Bit'), | |
35 | ('ref', 'Reference'), | |
36 | ('field', 'Field'), | |
37 | ('ref_field', 'Ref field'), | |
38 | ('level2', 'L2'), | |
39 | ('ref_level2', 'Ref L2'), | |
40 | ) | |
41 | annotation_rows = ( | |
42 | ('bits', 'Bits', (0,)), | |
43 | ('compare', 'Compare', (1,)), | |
44 | ('fields', 'Fields', (2,)), | |
45 | ('ref_fields', 'Ref fields', (3,)), | |
46 | ('level2', 'L2', (4,)), | |
47 | ('ref_level2', 'Ref L2', (5,)), | |
48 | ) | |
49 | options = ( | |
50 | {'id': 'displayas', 'desc': 'Display as', 'default': 'Nibble - Hex', | |
51 | 'values': ('Byte - Hex', 'Byte - Hex rev', 'Byte - BCD', | |
52 | 'Byte - BCD rev', 'Nibble - Hex', 'Nibble - Hex rev', 'Nibble - BCD', | |
53 | 'Nibble - BCD rev')}, | |
54 | {'id': 'synclen', 'desc': 'Sync length', 'default': '4', | |
55 | 'values': ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10')}, | |
56 | {'id': 'syncoffset', 'desc': 'Sync offset', 'default': '0', | |
57 | 'values': ('-4', '-3', '-2', '-1', '0', '1', '2', '3', '4')}, | |
58 | {'id': 'refsample', 'desc': 'Compare', 'default': 'off', 'values': | |
59 | ('off', 'show numbers', '1', '2', '3', '4', '5', '6', '7', '8', '9', | |
60 | '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', | |
61 | '21', '22', '23', '24', '25', '26', '27', '28', '29', '30')}, | |
62 | ) | |
63 | ||
64 | def __init__(self): | |
65 | self.reset() | |
66 | ||
67 | def reset(self): | |
68 | self.decoded = [] # Local cache of decoded OOK. | |
69 | self.ookstring = '' | |
70 | self.ookcache = [] | |
71 | self.trace_num = 0 | |
72 | ||
73 | def start(self): | |
74 | self.out_ann = self.register(srd.OUTPUT_ANN) | |
75 | self.out_python = self.register(srd.OUTPUT_PYTHON) | |
76 | self.displayas = self.options['displayas'] | |
77 | self.sync_length = self.options['synclen'] | |
78 | self.sync_offset = self.options['syncoffset'] | |
79 | self.ref = self.options['refsample'] | |
80 | ||
81 | def putx(self, data): | |
82 | self.put(self.ss, self.es, self.out_ann, data) | |
83 | ||
84 | def putp(self, data): | |
85 | self.put(self.ss, self.es, self.out_python, data) | |
86 | ||
87 | def display_level2(self, bits, line): | |
88 | self.decode_pos = 0 | |
89 | ook = self.decoded | |
90 | # Find the end of the preamble which could be 1010 or 1111. | |
91 | if len(ook) > 1: | |
92 | preamble_end = len(ook) + 1 | |
93 | char_first = ook[0][2] | |
94 | char_second = ook[1][2] | |
95 | if char_first == char_second: # 1111 | |
96 | preamble = '1111' | |
97 | char_last = char_first | |
98 | else: | |
99 | preamble = '1010' | |
100 | char_last = char_second | |
101 | for i in range(len(ook)): | |
102 | if preamble == '1111': | |
103 | if ook[i][2] != char_last: | |
104 | preamble_end = i | |
105 | break | |
106 | else: | |
107 | char_last = ook[i][2] | |
108 | else: | |
109 | if ook[i][2] != char_last: | |
110 | char_last = ook[i][2] | |
111 | else: | |
112 | preamble_end = i | |
113 | break | |
114 | ||
115 | if len(ook) >= preamble_end: | |
116 | preamble_end += int(self.sync_offset) - 1 | |
3d188680 | 117 | self.ss, self.es = ook[0][0], ook[preamble_end][1] |
51753e22 S |
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] | |
3d188680 | 152 | bits = 4 if 'Nibble' in self.displayas else 8 |
51753e22 S |
153 | rem_nibbles = len(self.ookstring) // bits |
154 | for i in range(rem_nibbles): # Display the rest of the nibbles. | |
155 | self.ss = ook[self.decode_pos][0] | |
156 | self.es = ook[self.decode_pos + bits - 1][1] | |
157 | self.put_field(bits, 2) | |
158 | ||
159 | self.display_level2(bits, 4) # Display L2 decode. | |
160 | ||
161 | if (self.ref != 'off' and self.ref != 'show numbers' and | |
162 | len(self.ookcache) >= int(self.ref)): # Compare traces. | |
163 | ref = int(self.ref) - 1 | |
164 | self.display_ref(self.trace_num, ref) | |
165 | if len(self.ookcache) == int(self.ref): # Backfill. | |
166 | for i in range(0, ref): | |
167 | self.display_ref(i, ref) | |
168 | elif self.ref == 'show numbers': # Display ref numbers. | |
169 | self.ss = self.ookcache[self.trace_num][0][0] | |
170 | end_sig = len(self.ookcache[self.trace_num]) - 1 | |
171 | self.es = self.ookcache[self.trace_num][end_sig][1] | |
172 | self.putx([1, [str(self.trace_num + 1)]]) | |
173 | ||
174 | def display_ref(self, t_num, ref): | |
175 | display_len = len(self.ookcache[ref]) | |
176 | if len(self.ookcache[t_num]) < len(self.ookcache[ref]): | |
177 | display_len = len(self.ookcache[t_num]) | |
178 | for i in range(display_len): | |
179 | self.ss = self.ookcache[t_num][i][0] | |
180 | self.es = self.ookcache[t_num][i][1] | |
181 | self.putx([1, [self.ookcache[ref][i][2]]]) | |
182 | ||
183 | def add_to_cache(self): # Cache the OOK so it can be used as a reference. | |
184 | self.ookcache.append(self.decoded) | |
185 | ||
186 | def decode(self, ss, es, data): | |
187 | self.decoded = data | |
188 | self.add_to_cache() | |
189 | self.display_all() | |
190 | self.ookstring = '' | |
191 | self.trace_num += 1 | |
192 | self.ss = ss | |
193 | self.es = es | |
194 | self.putp(data) # Send data up the stack. |