summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2020-02-22 10:19:26 +0100
committerGerhard Sittig <gerhard.sittig@gmx.net>2020-07-18 15:48:50 +0200
commit4032deddd46665c16254abfd7729753930f0c32e (patch)
treebc840a60c8bb25b7c5bc36b9237235e481ee6cae
parent02993c7a0c746d9f47f2a7c50273c76a5a7332cd (diff)
downloadlibsigrokdecode-4032deddd46665c16254abfd7729753930f0c32e.tar.gz
libsigrokdecode-4032deddd46665c16254abfd7729753930f0c32e.zip
ir_irmp: introduce IRMP based decoder for infrared signals
Commit the decoder as it was provided by Rene Staffen. Which appears to be a slightly modified version of one of the other IR decoders, though the boilerplate doesn't say so.
-rw-r--r--decoders/ir_irmp/__init__.py25
-rw-r--r--decoders/ir_irmp/pd.py149
2 files changed, 174 insertions, 0 deletions
diff --git a/decoders/ir_irmp/__init__.py b/decoders/ir_irmp/__init__.py
new file mode 100644
index 0000000..5b0e813
--- /dev/null
+++ b/decoders/ir_irmp/__init__.py
@@ -0,0 +1,25 @@
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+##
+
+'''
+IRMP is a multi protocol infrared remote protocol decoder
+intiated and maintained by Frank M. (ukw)
+
+https://www.mikrocontroller.net/articles/IRMP
+
+irmp wrapper by René Staffen
+'''
+
+from .pd import Decoder
diff --git a/decoders/ir_irmp/pd.py b/decoders/ir_irmp/pd.py
new file mode 100644
index 0000000..343c068
--- /dev/null
+++ b/decoders/ir_irmp/pd.py
@@ -0,0 +1,149 @@
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+##
+
+import sigrokdecode as srd
+
+#from .lists import *
+
+from .IrmpPythonWrap import IrmpWrap
+
+class SamplerateError(Exception):
+ pass
+
+class Decoder(srd.Decoder):
+ api_version = 3
+ id = 'ir_irmp'
+ name = 'IR IRMP'
+ longname = 'IR IRMP multi protocol decoder'
+ desc = 'IRMP - multi protocol infrared decoder with support for many IR protocols by Frank M. (ukw)'
+ license = 'gplv2+'
+ inputs = ['logic']
+ outputs = []
+ tags = ['IR']
+ channels = (
+ {'id': 'ir', 'name': 'IR', 'desc': 'Data line'},
+ )
+ options = (
+ {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
+ 'values': ('active-low', 'active-high')},
+#
+# {'id': 'cd_freq', 'desc': 'Carrier Frequency', 'default': 0},
+ )
+ annotations = (
+ ('packet', 'Packet'),
+ ('debug', 'Debug'),
+ )
+ annotation_rows = (
+ ('packets', 'IR Packets', (0,)),
+ ('debug', 'Debug', (1,)),
+ )
+ irmp = IrmpWrap()
+
+ def putIr(self, data):
+ ss = data['start'] * self.subSample
+ es = data['end'] * self.subSample
+ ad = data['data']['address']
+ pr = data['data']['protocol']
+ pn = data['data']['protocolName']
+ cm = data['data']['command']
+ repeat = data['data']['repeat']
+
+
+ # print(f" {self.samplenum} {ss} - {es} ({data['start']} - {data['end']})")
+ self.put(ss, es, self.out_ann,
+ [0, [ f"Protocol: {pn} ({pr}), Address 0x{ad:04x}, Command: 0x{cm:04x} {'repeated' if repeat else ''}",
+ f"P: {pn} ({pr}), Ad: 0x{ad:x}, Cmd: 0x{cm:x} {'rep' if repeat else ''}",
+ f"P: {pr} A: 0x{ad:x} C: 0x{cm:x} {'rep' if repeat else ''}",
+ f"C:{cm:x} A:{ad:x} {'r' if repeat else ''}",
+ f"C:{cm:x}",
+ ]])
+
+ def __init__(self):
+ self.irmp = Decoder.irmp
+ self.reset()
+
+ def reset(self):
+ self.irmp.Reset()
+
+ def start(self):
+ self.out_ann = self.register(srd.OUTPUT_ANN)
+
+ def metadata(self, key, value):
+ if key == srd.SRD_CONF_SAMPLERATE:
+ self.samplerate = value
+
+
+ def decode(self):
+ if not self.samplerate:
+ raise SamplerateError('Cannot decode without samplerate.')
+
+
+ if (self.samplerate % self.irmp.GetSampleRate()) != 0:
+ raise SamplerateError(f'samplerate has to be multple of {self.irmp.GetSampleRate()}' )
+
+ self.subSample = int(self.samplerate / self.irmp.GetSampleRate())
+ sampleSkip = self.subSample
+ #self.reset()
+ #print (f" startdecode: samplenum {self.samplenum} rate: {self.samplerate} subsample {self.subSample}")
+ # cd_count = None
+ # if self.options['cd_freq']:
+ # cd_count = int(self.samplerate / self.options['cd_freq']) + 1
+
+ self.active = 0 if self.options['polarity'] == 'active-low' else 1
+
+ (ir,) = self.wait([{'skip' : sampleSkip}])
+ i = 0
+
+ while True:
+ ##### todo: check if ir carrier frequency detection can be used
+ #
+ # Detect changes in the presence of an active input signal.
+ # The decoder can either be fed an already filtered RX signal
+ # or optionally can detect the presence of a carrier. Periods
+ # of inactivity (signal changes slower than the carrier freq,
+ # if specified) pass on the most recently sampled level. This
+ # approach works for filtered and unfiltered input alike, and
+ # only slightly extends the active phase of input signals with
+ # carriers included by one period of the carrier frequency.
+ # IR based communication protocols can cope with this slight
+ # inaccuracy just fine by design. Enabling carrier detection
+ # on already filtered signals will keep the length of their
+ # active period, but will shift their signal changes by one
+ # carrier period before they get passed to decoding logic.
+ # if cd_count:
+ # (cur_ir,) = self.wait([{0: 'e'}, {'skip': cd_count}])
+ # if self.matched[0]:
+ # cur_ir = self.active
+ # if cur_ir == prev_ir:
+ # continue
+ # prev_ir = cur_ir
+ # self.ir = cur_ir
+ # else:
+ # (self.ir,) = self.wait({0: 'e'})
+ #
+ #print (f"samplenum {self.samplenum}")
+ #if i%100 == 0:
+ # self.put(self.samplenum, self.samplenum+10, self.out_ann,
+ # [1, [ f"{self.samplenum} - {i}",]])
+
+ if self.active == 1:
+ ir = 1 - ir
+
+ if self.irmp.AddSample(ir):
+ data = self.irmp.GetData()
+ self.putIr(data)
+ i = i + 1
+ (ir,) = self.wait([{'skip' : sampleSkip}])
+