]> sigrok.org Git - libsigrokdecode.git/blob - decoders/ir_irmp/pd.py
343c068cb5b870df7532cea133a4a8e0f75d68bc
[libsigrokdecode.git] / decoders / ir_irmp / pd.py
1 ##
2 ## This program is free software; you can redistribute it and/or modify
3 ## it under the terms of the GNU General Public License as published by
4 ## the Free Software Foundation; either version 2 of the License, or
5 ## (at your option) any later version.
6 ##
7 ## This program is distributed in the hope that it will be useful,
8 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ## GNU General Public License for more details.
11 ##
12 ## You should have received a copy of the GNU General Public License
13 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
14 ##
15
16 import sigrokdecode as srd
17
18 #from .lists import *
19
20 from .IrmpPythonWrap import IrmpWrap
21
22 class SamplerateError(Exception):
23     pass
24
25 class Decoder(srd.Decoder):
26     api_version = 3
27     id = 'ir_irmp'
28     name = 'IR IRMP'
29     longname = 'IR IRMP multi protocol decoder'
30     desc = 'IRMP - multi protocol infrared decoder with support for many IR protocols by Frank M. (ukw)'
31     license = 'gplv2+'
32     inputs = ['logic']
33     outputs = []
34     tags = ['IR']
35     channels = (
36         {'id': 'ir', 'name': 'IR', 'desc': 'Data line'},
37     )
38     options = (
39         {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
40             'values': ('active-low', 'active-high')},
41 #
42 #        {'id': 'cd_freq', 'desc': 'Carrier Frequency', 'default': 0},
43     )
44     annotations = (
45         ('packet', 'Packet'),
46         ('debug', 'Debug'),
47     )
48     annotation_rows = (
49         ('packets', 'IR Packets', (0,)),
50         ('debug', 'Debug', (1,)),
51     )
52     irmp = IrmpWrap()
53
54     def putIr(self, data):
55         ss     = data['start'] * self.subSample
56         es     = data['end']   * self.subSample
57         ad     = data['data']['address']
58         pr     = data['data']['protocol']
59         pn     = data['data']['protocolName']
60         cm     = data['data']['command']
61         repeat = data['data']['repeat']
62         
63         
64        # print(f" {self.samplenum}  {ss} - {es} ({data['start']} - {data['end']})")
65         self.put(ss, es, self.out_ann,
66                  [0, [ f"Protocol: {pn} ({pr}), Address 0x{ad:04x}, Command: 0x{cm:04x} {'repeated' if repeat else ''}",
67                        f"P: {pn} ({pr}), Ad: 0x{ad:x}, Cmd: 0x{cm:x} {'rep' if repeat else ''}",
68                        f"P: {pr}  A: 0x{ad:x} C: 0x{cm:x} {'rep' if repeat else ''}",
69                        f"C:{cm:x} A:{ad:x} {'r' if repeat else ''}",
70                        f"C:{cm:x}",
71                      ]])
72
73     def __init__(self):
74         self.irmp = Decoder.irmp
75         self.reset()
76
77     def reset(self):
78         self.irmp.Reset()
79
80     def start(self):
81         self.out_ann = self.register(srd.OUTPUT_ANN)
82
83     def metadata(self, key, value):
84         if key == srd.SRD_CONF_SAMPLERATE:
85             self.samplerate = value
86
87
88     def decode(self):
89         if not self.samplerate:
90             raise SamplerateError('Cannot decode without samplerate.')
91
92         
93         if (self.samplerate % self.irmp.GetSampleRate()) != 0:
94             raise SamplerateError(f'samplerate has to be multple of {self.irmp.GetSampleRate()}' )
95             
96         self.subSample  = int(self.samplerate / self.irmp.GetSampleRate())
97         sampleSkip = self.subSample
98         #self.reset()
99         #print (f" startdecode: samplenum {self.samplenum} rate: {self.samplerate} subsample {self.subSample}")
100         # cd_count = None
101         # if self.options['cd_freq']:
102         #     cd_count = int(self.samplerate / self.options['cd_freq']) + 1
103         
104         self.active = 0 if self.options['polarity'] == 'active-low' else 1
105
106         (ir,) = self.wait([{'skip' : sampleSkip}])
107         i = 0
108
109         while True:
110             ##### todo: check if ir carrier frequency detection can be used
111             #
112             # Detect changes in the presence of an active input signal.
113             # The decoder can either be fed an already filtered RX signal
114             # or optionally can detect the presence of a carrier. Periods
115             # of inactivity (signal changes slower than the carrier freq,
116             # if specified) pass on the most recently sampled level. This
117             # approach works for filtered and unfiltered input alike, and
118             # only slightly extends the active phase of input signals with
119             # carriers included by one period of the carrier frequency.
120             # IR based communication protocols can cope with this slight
121             # inaccuracy just fine by design. Enabling carrier detection
122             # on already filtered signals will keep the length of their
123             # active period, but will shift their signal changes by one
124             # carrier period before they get passed to decoding logic.
125             #   if cd_count:
126             #       (cur_ir,) = self.wait([{0: 'e'}, {'skip': cd_count}])
127             #       if self.matched[0]:
128             #           cur_ir = self.active
129             #       if cur_ir == prev_ir:
130             #           continue
131             #       prev_ir = cur_ir
132             #       self.ir = cur_ir
133             #   else:
134             #       (self.ir,) = self.wait({0: 'e'})
135             #   
136             #print (f"samplenum {self.samplenum}")
137             #if i%100 == 0:
138             #    self.put(self.samplenum, self.samplenum+10, self.out_ann,
139             #             [1, [ f"{self.samplenum}  - {i}",]])
140
141             if self.active == 1:
142                 ir = 1 - ir
143                 
144             if self.irmp.AddSample(ir):
145                 data = self.irmp.GetData()
146                 self.putIr(data)
147             i = i + 1
148             (ir,) = self.wait([{'skip' : sampleSkip}])
149