sae_j1850_vpw: rewrite decoder to improve usability and maintenance
[libsigrokdecode/gsi.git] / decoders / ir_rc6 / pd.py
blobe195dbd161ed129e9a541efe0be9f1c2d4cfae26
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.
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
22 class SamplerateError(Exception):
23 pass
25 class Decoder(srd.Decoder):
26 api_version = 3
27 id = 'ir_rc6'
28 name = 'IR RC-6'
29 longname = 'IR RC-6'
30 desc = 'RC-6 infrared remote control protocol.'
31 license = 'gplv2+'
32 inputs = ['logic']
33 outputs = []
34 tags = ['IR']
35 channels = (
36 {'id': 'ir', 'name': 'IR', 'desc': 'IR data line'},
38 options = (
39 {'id': 'polarity', 'desc': 'Polarity', 'default': 'auto',
40 'values': ('auto', 'active-low', 'active-high')},
42 annotations = (
43 ('bit', 'Bit'),
44 ('sync', 'Sync'),
45 ('startbit', 'Startbit'),
46 ('field', 'Field'),
47 ('togglebit', 'Togglebit'),
48 ('address', 'Address'),
49 ('command', 'Command'),
51 annotation_rows = (
52 ('bits', 'Bits', (0,)),
53 ('fields', 'Fields', (1, 2, 3, 4, 5, 6)),
56 def __init__(self):
57 self.reset()
59 def reset(self):
60 self.samplerate = None
61 self.edges, self.deltas, self.bits = [], [], []
62 self.state = 'IDLE'
63 self.mode = 0
65 def start(self):
66 self.out_ann = self.register(srd.OUTPUT_ANN)
68 def metadata(self, key, value):
69 if key == srd.SRD_CONF_SAMPLERATE:
70 self.samplerate = value
71 # One bit: 0.889ms (one half low, one half high).
72 self.halfbit = int((self.samplerate * 0.000889) / 2.0)
74 def putb(self, bit, data):
75 self.put(bit[0], bit[1], self.out_ann, data)
77 def putbits(self, bit1, bit2, data):
78 self.put(bit1[0], bit2[1], self.out_ann, data)
80 def putx(self, ss, es, data):
81 self.put(ss, es, self.out_ann, data)
83 def handle_bit(self):
84 if len(self.bits) != 6:
85 return
86 if self.bits[0][2] == 8 and self.bits[0][3] == 1:
87 self.putb(self.bits[0], [1, ['Synchronisation', 'Sync']])
88 else:
89 return
90 if self.bits[1][3] == 1:
91 self.putb(self.bits[1], [2, ['Startbit', 'Start']])
92 else:
93 return
94 self.mode = sum([self.bits[2 + i][3] << (2 - i) for i in range(3)])
95 self.putbits(self.bits[2], self.bits[4], [3, ['Field: %d' % self.mode]])
96 self.putb(self.bits[5], [4, ['Toggle: %d' % self.bits[5][3]]])
98 def handle_package(self):
99 # Sync and start bits have to be 1.
100 if self.bits[0][3] == 0 or self.bits[1][3] == 0:
101 return
102 if len(self.bits) <= 6:
103 return
105 if self.mode == 0 and len(self.bits) == 22: # Mode 0 standard
106 value = sum([self.bits[6 + i][3] << (7 - i) for i in range(8)])
107 self.putbits(self.bits[6], self.bits[13], [5, ['Address: %0.2X' % value]])
109 value = sum([self.bits[14 + i][3] << (7 - i) for i in range(8)])
110 self.putbits(self.bits[14], self.bits[21], [6, ['Data: %0.2X' % value]])
112 self.bits = []
114 if self.mode == 6 and len(self.bits) >= 15: # Mode 6
115 if self.bits[6][3] == 0: # Short addr, Mode 6A
116 value = sum([self.bits[6 + i][3] << (7 - i) for i in range(8)])
117 self.putbits(self.bits[6], self.bits[13], [5, ['Address: %0.2X' % value]])
119 num_data_bits = len(self.bits) - 14
120 value = sum([self.bits[14 + i][3] << (num_data_bits - 1 - i) for i in range(num_data_bits)])
121 self.putbits(self.bits[14], self.bits[-1], [6, ['Data: %X' % value]])
123 self.bits = []
125 elif len(self.bits) >= 23: # Long addr, Mode 6B
126 value = sum([self.bits[6 + i][3] << (15 - i) for i in range(16)])
127 self.putbits(self.bits[6], self.bits[21], [5, ['Address: %0.2X' % value]])
129 num_data_bits = len(self.bits) - 22
130 value = sum([self.bits[22 + i][3] << (num_data_bits - 1 - i) for i in range(num_data_bits)])
131 self.putbits(self.bits[22], self.bits[-1], [6, ['Data: %X' % value]])
133 self.bits = []
135 def decode(self):
136 if not self.samplerate:
137 raise SamplerateError('Cannot decode without samplerate.')
138 value = 0
139 num_edges = -1
140 self.invert = False
142 while True:
143 conditions = [{0: 'e'}]
144 if self.state == 'DATA':
145 conditions.append({'skip': self.halfbit * 6})
146 (self.ir,) = self.wait(conditions)
148 if len(conditions) == 2:
149 if self.matched[1]:
150 self.state = 'IDLE'
152 self.edges.append(self.samplenum)
153 if len(self.edges) < 2:
154 continue
156 delta = (self.edges[-1] - self.edges[-2]) / self.halfbit
157 delta = int(delta + 0.5)
158 self.deltas.append(delta)
160 if len(self.deltas) < 2:
161 continue
163 if self.deltas[-2:] == [6, 2]:
164 self.state = 'SYNC'
165 num_edges = 0
166 self.bits = []
168 if self.options['polarity'] == 'auto':
169 value = 1
170 else:
171 value = self.ir if self.options['polarity'] == 'active-high' else 1 - self.ir
173 self.bits.append((self.edges[-3], self.edges[-1], 8, value))
174 self.invert = self.ir == 0
175 self.putb(self.bits[-1], [0, ['%d' % value]]) # Add bit.
177 if (num_edges % 2) == 0: # Only count every second edge.
178 if self.deltas[-2] in [1, 2, 3] and self.deltas[-1] in [1, 2, 3, 6]:
179 self.state = 'DATA'
180 if self.deltas[-2] != self.deltas[-1]:
181 # Insert border between 2 bits.
182 self.edges.insert(-1, self.edges[-2] + self.deltas[-2] * self.halfbit)
183 total = self.deltas[-1]
184 self.deltas[-1] = self.deltas[-2]
185 self.deltas.append(total - self.deltas[-1])
187 self.bits.append((self.edges[-4], self.edges[-2], self.deltas[-2] * 2, value))
189 num_edges += 1
190 else:
191 self.bits.append((self.edges[-3], self.edges[-1], self.deltas[-1] * 2, value))
193 self.putb(self.bits[-1], [0, ['%d' % value]]) # Add bit.
195 if len(self.bits) > 0:
196 self.handle_bit()
197 if self.state == 'IDLE':
198 self.handle_package()
200 if self.options['polarity'] == 'auto':
201 value = self.ir if self.invert else 1 - self.ir
202 else:
203 value = self.ir if self.options['polarity'] == 'active-low' else 1 - self.ir
205 num_edges += 1