]> sigrok.org Git - libsigrokdecode.git/blame - decoders/ir_irmp/pd.py
ir_irmp: touch up the IRMP based decoder implementation (Python side)
[libsigrokdecode.git] / decoders / ir_irmp / pd.py
CommitLineData
4032dedd 1##
e8e8bec6
GS
2## This file is part of the libsigrokdecode project.
3##
4## Copyright (C) 2014 Gump Yang <gump.yang@gmail.com>
5## Copyright (C) 2019 Rene Staffen
6##
4032dedd
GS
7## This program is free software; you can redistribute it and/or modify
8## it under the terms of the GNU General Public License as published by
9## the Free Software Foundation; either version 2 of the License, or
10## (at your option) any later version.
11##
12## This program is distributed in the hope that it will be useful,
13## but WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15## GNU General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with this program; if not, see <http://www.gnu.org/licenses/>.
19##
20
e8e8bec6 21from . import irmp_library
4032dedd
GS
22import sigrokdecode as srd
23
4032dedd
GS
24class SamplerateError(Exception):
25 pass
26
27class Decoder(srd.Decoder):
28 api_version = 3
29 id = 'ir_irmp'
30 name = 'IR IRMP'
e8e8bec6
GS
31 longname = 'IR IRMP'
32 desc = 'IRMP infrared remote control multi protocol.'
4032dedd
GS
33 license = 'gplv2+'
34 inputs = ['logic']
35 outputs = []
36 tags = ['IR']
37 channels = (
38 {'id': 'ir', 'name': 'IR', 'desc': 'Data line'},
39 )
40 options = (
41 {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
42 'values': ('active-low', 'active-high')},
4032dedd
GS
43 )
44 annotations = (
45 ('packet', 'Packet'),
4032dedd
GS
46 )
47 annotation_rows = (
48 ('packets', 'IR Packets', (0,)),
4032dedd 49 )
4032dedd 50
e8e8bec6
GS
51 def putframe(self, data):
52 nr = data['proto_nr']
53 name = data['proto_name']
54 addr = data['address']
55 cmd = data['command']
56 repeat = data['repeat']
57 rep = ['repeat', 'rep', 'r'] if repeat else ['', '', '']
58 ss = data['start'] * self.rate_factor
59 es = data['end'] * self.rate_factor
60 self.put(ss, es, self.out_ann, [0, [
61 'Protocol: {nr} ({name}), Address 0x{addr:04x}, Command: 0x{cmd:04x} {rep[0]}'.format(**locals()),
62 'P: {name} ({nr}), Addr: 0x{addr:x}, Cmd: 0x{cmd:x} {rep[1]}'.format(**locals()),
63 'P: {nr} A: 0x{addr:x} C: 0x{cmd:x} {rep[1]}'.format(**locals()),
64 'C:{cmd:x} A:{addr:x} {rep[2]}'.format(**locals()),
65 'C:{cmd:x}'.format(**locals()),
66 ]])
4032dedd
GS
67
68 def __init__(self):
e8e8bec6
GS
69 self.irmp = irmp_library.IrmpLibrary()
70 self.lib_rate = self.irmp.get_sample_rate()
4032dedd
GS
71 self.reset()
72
73 def reset(self):
e8e8bec6 74 self.irmp.reset_state()
4032dedd
GS
75
76 def start(self):
77 self.out_ann = self.register(srd.OUTPUT_ANN)
78
79 def metadata(self, key, value):
80 if key == srd.SRD_CONF_SAMPLERATE:
81 self.samplerate = value
82
4032dedd
GS
83 def decode(self):
84 if not self.samplerate:
85 raise SamplerateError('Cannot decode without samplerate.')
e8e8bec6
GS
86 if self.samplerate % self.lib_rate:
87 raise SamplerateError('capture samplerate must be multiple of library samplerate ({})'.format(self.lib_rate))
88 self.rate_factor = int(self.samplerate / self.lib_rate)
4032dedd 89
4032dedd 90 self.active = 0 if self.options['polarity'] == 'active-low' else 1
e8e8bec6 91 ir, = self.wait()
4032dedd 92 while True:
4032dedd
GS
93 if self.active == 1:
94 ir = 1 - ir
e8e8bec6
GS
95 if self.irmp.add_one_sample(ir):
96 data = self.irmp.get_result_data()
97 self.putframe(data)
98 ir, = self.wait([{'skip': self.rate_factor}])