]> sigrok.org Git - libsigrokdecode.git/blob - decoders/ir_irmp/pd.py
ef3da4dd3ac80f0fedfed0477dd84b3df6a31c6f
[libsigrokdecode.git] / decoders / ir_irmp / pd.py
1 ##
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 ##
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
21 from . import irmp_library
22 import sigrokdecode as srd
23
24 class SamplerateError(Exception):
25     pass
26
27 class Decoder(srd.Decoder):
28     api_version = 3
29     id = 'ir_irmp'
30     name = 'IR IRMP'
31     longname = 'IR IRMP'
32     desc = 'IRMP infrared remote control multi protocol.'
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')},
43     )
44     annotations = (
45         ('packet', 'Packet'),
46     )
47     annotation_rows = (
48         ('packets', 'IR Packets', (0,)),
49     )
50
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         ]])
67
68     def __init__(self):
69         self.irmp = irmp_library.IrmpLibrary()
70         self.lib_rate = self.irmp.get_sample_rate()
71         self.reset()
72
73     def reset(self):
74         self.irmp.reset_state()
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
83     def decode(self):
84         if not self.samplerate:
85             raise SamplerateError('Cannot decode without samplerate.')
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)
89
90         self.active = 0 if self.options['polarity'] == 'active-low' else 1
91         ir, = self.wait()
92         while True:
93             if self.active == 1:
94                 ir = 1 - ir
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}])