]> sigrok.org Git - libsigrokdecode.git/blame - decoders/ir_rc6/pd.py
ir_rc6: Reduce nesting level.
[libsigrokdecode.git] / decoders / ir_rc6 / pd.py
CommitLineData
8249f091
B
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.
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
21
22class SamplerateError(Exception):
23 pass
24
25class 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'},
37 )
38 options = (
39 {'id': 'polarity', 'desc': 'Polarity', 'default': 'auto',
40 'values': ('auto', 'active-low', 'active-high')},
41 )
42 annotations = (
43 ('bit', 'Bit'),
44 ('sync', 'Sync'),
45 ('startbit', 'Startbit'),
46 ('field', 'Field'),
47 ('togglebit', 'Togglebit'),
48 ('address', 'Address'),
49 ('command', 'Command'),
50 )
51 annotation_rows = (
52 ('bits', 'Bits', (0,)),
53 ('fields', 'Fields', (1, 2, 3, 4, 5, 6)),
54 )
55
56 def __init__(self):
57 self.reset()
58
59 def reset(self):
60 self.samplerate = None
61 self.samplenum = None
62 self.edges, self.deltas, self.bits = [], [], []
63 self.state = 'IDLE'
64 self.mode = 0
65
66 def start(self):
67 self.out_ann = self.register(srd.OUTPUT_ANN)
68
69 def metadata(self, key, value):
70 if key == srd.SRD_CONF_SAMPLERATE:
71 self.samplerate = value
72 # One bit: 0.889ms (one half low, one half high).
73 self.halfbit = int((self.samplerate * 0.000889) / 2.0)
74
75 def putb(self, bit, data):
76 self.put(bit[0], bit[1], self.out_ann, data)
77
78 def putbits(self, bit1, bit2, data):
79 self.put(bit1[0], bit2[1], self.out_ann, data)
80
81 def putx(self, ss, es, data):
82 self.put(ss, es, self.out_ann, data)
83
84 def handle_bit(self):
0700c903
UH
85 if len(self.bits) != 6:
86 return
87 if self.bits[0][2] == 8 and self.bits[0][3] == 1:
88 self.putb(self.bits[0], [1, ['Synchronisation', 'Sync']])
89 else:
90 return
91 if self.bits[1][3] == 1:
92 self.putb(self.bits[1], [2, ['Startbit', 'Start']])
93 else:
94 return
95 self.mode = sum([self.bits[2 + i][3] << (2 - i) for i in range(3)])
96 self.putbits(self.bits[2], self.bits[4], [3, ['Field: %d' % self.mode]])
97 self.putb(self.bits[5], [4, ['Toggle: %d' % self.bits[5][3]]])
8249f091
B
98
99 def handle_package(self):
100 # Sync and start bits have to be 1.
101 if self.bits[0][3] == 0 or self.bits[1][3] == 0:
102 return
0700c903
UH
103 if len(self.bits) <= 6:
104 return
105
106 if self.mode == 0 and len(self.bits) == 22: # Mode 0 standard
107 value = sum([self.bits[6 + i][3] << (7 - i) for i in range(8)])
108 self.putbits(self.bits[6], self.bits[13], [5, ['Address: %0.2X' % value]])
8249f091 109
0700c903
UH
110 value = sum([self.bits[14 + i][3] << (7 - i) for i in range(8)])
111 self.putbits(self.bits[14], self.bits[21], [6, ['Data: %0.2X' % value]])
8249f091 112
0700c903 113 self.bits = []
8249f091 114
0700c903
UH
115 if self.mode == 6 and len(self.bits) >= 15: # Mode 6
116 if self.bits[6][3] == 0: # Short addr, Mode 6A
117 value = sum([self.bits[6 + i][3] << (7 - i) for i in range(8)])
118 self.putbits(self.bits[6], self.bits[13], [5, ['Address: %0.2X' % value]])
8249f091 119
0700c903
UH
120 num_data_bits = len(self.bits) - 14
121 value = sum([self.bits[14 + i][3] << (num_data_bits - 1 - i) for i in range(num_data_bits)])
122 self.putbits(self.bits[14], self.bits[-1], [6, ['Data: %X' % value]])
8249f091 123
0700c903 124 self.bits = []
8249f091 125
0700c903
UH
126 elif len(self.bits) >= 23: # Long addr, Mode 6B
127 value = sum([self.bits[6 + i][3] << (15 - i) for i in range(16)])
128 self.putbits(self.bits[6], self.bits[21], [5, ['Address: %0.2X' % value]])
8249f091 129
0700c903
UH
130 num_data_bits = len(self.bits) - 22
131 value = sum([self.bits[22 + i][3] << (num_data_bits - 1 - i) for i in range(num_data_bits)])
132 self.putbits(self.bits[22], self.bits[-1], [6, ['Data: %X' % value]])
8249f091 133
0700c903 134 self.bits = []
8249f091
B
135
136 def decode(self):
137 if not self.samplerate:
138 raise SamplerateError('Cannot decode without samplerate.')
139 value = 0
140 num_edges = -1
141 self.invert = False
142
143 while True:
144 conditions = [{0: 'e'}]
145 if self.state == 'DATA':
146 conditions.append({'skip': self.halfbit * 6})
147 (self.ir,) = self.wait(conditions)
148
149 if len(conditions) == 2:
150 if self.matched[1]:
151 self.state = 'IDLE'
152
153 self.edges.append(self.samplenum)
154 if len(self.edges) < 2:
155 continue
156
157 delta = (self.edges[-1] - self.edges[-2]) / self.halfbit
158 delta = int(delta + 0.5)
159 self.deltas.append(delta)
160
161 if len(self.deltas) < 2:
162 continue
163
164 if self.deltas[-2:] == [6, 2]:
165 self.state = 'SYNC'
166 num_edges = 0
167 self.bits = []
168
169 if self.options['polarity'] == 'auto':
170 value = 1
171 else:
172 value = self.ir if self.options['polarity'] == 'active-high' else 1 - self.ir
173
174 self.bits.append((self.edges[-3], self.edges[-1], 8, value))
175 self.invert = self.ir == 0
176 self.putb(self.bits[-1], [0, ['%d' % value]]) # Add bit.
177
178 if (num_edges % 2) == 0: # Only count every second edge.
179 if self.deltas[-2] in [1, 2, 3] and self.deltas[-1] in [1, 2, 3, 6]:
180 self.state = 'DATA'
181 if self.deltas[-2] != self.deltas[-1]:
182 # Insert border between 2 bits.
183 self.edges.insert(-1, self.edges[-2] + self.deltas[-2] * self.halfbit)
184 total = self.deltas[-1]
185 self.deltas[-1] = self.deltas[-2]
186 self.deltas.append(total - self.deltas[-1])
187
188 self.bits.append((self.edges[-4], self.edges[-2], self.deltas[-2] * 2, value))
189
190 num_edges += 1
191 else:
192 self.bits.append((self.edges[-3], self.edges[-1], self.deltas[-1] * 2, value))
193
194 self.putb(self.bits[-1], [0, ['%d' % value]]) # Add bit.
195
196 if len(self.bits) > 0:
197 self.handle_bit()
198 if self.state == 'IDLE':
199 self.handle_package()
200
201 if self.options['polarity'] == 'auto':
202 value = self.ir if self.invert else 1 - self.ir
203 else:
204 value = self.ir if self.options['polarity'] == 'active-low' else 1 - self.ir
205
206 num_edges += 1