summaryrefslogtreecommitdiff
path: root/decoders
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2020-07-25 17:56:54 +0200
committerGerhard Sittig <gerhard.sittig@gmx.net>2020-07-25 23:21:23 +0200
commit17e0ba228dadb7a12aa0e11fa81fcbc4a7836349 (patch)
tree9dbb186a5df732c292e48862525c0da0b5bb97e2 /decoders
parent025c728ed12e33121fb5be4ce14085afc2f23853 (diff)
downloadlibsigrokdecode-17e0ba228dadb7a12aa0e11fa81fcbc4a7836349.tar.gz
libsigrokdecode-17e0ba228dadb7a12aa0e11fa81fcbc4a7836349.zip
ir_nec: add support for extended NEC protocol (16bit address)
Add support for the extended NEC protocol, where the address field spans 16 bits and the complement is not sent. Commands still span 8 bits and are sent in normal and in inverted form. The user needs to select the extended protocol (off by default for compatibility), the input data does not allow automatic detection of the protocol variant. It's also not appropriate to assume the extended format when the address field happens to fail the validity check. The unfortunate mix of data value checks and annotation emission in combination with "global" state makes this implementation more redundant than I would like. A later cleanup is desirable. This resolves bug #1583.
Diffstat (limited to 'decoders')
-rw-r--r--decoders/ir_nec/__init__.py1
-rw-r--r--decoders/ir_nec/pd.py41
2 files changed, 28 insertions, 14 deletions
diff --git a/decoders/ir_nec/__init__.py b/decoders/ir_nec/__init__.py
index c361c3d..c3ab293 100644
--- a/decoders/ir_nec/__init__.py
+++ b/decoders/ir_nec/__init__.py
@@ -19,6 +19,7 @@
'''
NEC is a pulse-distance based infrared remote control protocol.
+See https://www.sbprojects.net/knowledge/ir/nec.php for a description.
'''
from .pd import Decoder
diff --git a/decoders/ir_nec/pd.py b/decoders/ir_nec/pd.py
index af22f93..c05e474 100644
--- a/decoders/ir_nec/pd.py
+++ b/decoders/ir_nec/pd.py
@@ -49,6 +49,8 @@ class Decoder(srd.Decoder):
{'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
'values': ('active-low', 'active-high')},
{'id': 'cd_freq', 'desc': 'Carrier Frequency', 'default': 0},
+ {'id': 'extended', 'desc': 'Extended NEC Protocol',
+ 'default': 'no', 'values': ('yes', 'no')},
)
annotations = (
('bit', 'Bit'),
@@ -78,16 +80,17 @@ class Decoder(srd.Decoder):
def putb(self, data):
self.put(self.ss_bit, self.samplenum, self.out_ann, data)
- def putd(self, data):
+ def putd(self, data, bit_count):
name = self.state.title()
d = {'ADDRESS': Ann.ADDR, 'ADDRESS#': Ann.ADDR_INV,
'COMMAND': Ann.CMD, 'COMMAND#': Ann.CMD_INV}
s = {'ADDRESS': ['ADDR', 'A'], 'ADDRESS#': ['ADDR#', 'A#'],
'COMMAND': ['CMD', 'C'], 'COMMAND#': ['CMD#', 'C#']}
+ fmt = '{{}}: 0x{{:0{}X}}'.format(bit_count // 4)
self.putx([d[self.state], [
- '{}: 0x{:02X}'.format(name, data),
- '{}: 0x{:02X}'.format(s[self.state][0], data),
- '{}: 0x{:02X}'.format(s[self.state][1], data),
+ fmt.format(name, data),
+ fmt.format(s[self.state][0], data),
+ fmt.format(s[self.state][1], data),
s[self.state][1],
]])
@@ -155,24 +158,32 @@ class Decoder(srd.Decoder):
self.data.append(ret)
self.ss_bit = self.samplenum
- def data_ok(self, check):
+ def data_ok(self, check, want_len):
name = self.state.title()
normal, inverted = bitpack(self.data[:8]), bitpack(self.data[8:])
valid = (normal ^ inverted) == 0xff
show = inverted if self.state.endswith('#') else normal
- if len(self.data) == 8:
+ is_ext_addr = self.is_extended and self.state == 'ADDRESS'
+ if is_ext_addr:
+ normal = bitpack(self.data)
+ show = normal
+ valid = True
+ if len(self.data) == want_len:
if self.state == 'ADDRESS':
self.addr = normal
if self.state == 'COMMAND':
self.cmd = normal
- self.putd(show)
+ self.putd(show, want_len)
self.ss_start = self.samplenum
+ if is_ext_addr:
+ self.data = []
+ self.ss_bit = self.ss_start = self.samplenum
return True
if check and not valid:
warn_show = bitpack(self.data)
self.putx([Ann.WARN, ['{} error: 0x{:04X}'.format(name, warn_show)]])
else:
- self.putd(show)
+ self.putd(show, want_len)
self.data = []
self.ss_bit = self.ss_start = self.samplenum
return valid
@@ -188,6 +199,8 @@ class Decoder(srd.Decoder):
prev_ir = None
active = 0 if self.options['polarity'] == 'active-low' else 1
+ self.is_extended = self.options['extended'] == 'yes'
+ want_addr_len = 16 if self.is_extended else 8
while True:
# Detect changes in the presence of an active input signal.
@@ -238,22 +251,22 @@ class Decoder(srd.Decoder):
self.ss_bit = self.ss_start = self.samplenum
elif self.state == 'ADDRESS':
self.handle_bit(b)
- if len(self.data) == 8:
- self.data_ok(False)
- self.state = 'ADDRESS#'
+ if len(self.data) == want_addr_len:
+ self.data_ok(False, want_addr_len)
+ self.state = 'COMMAND' if self.is_extended else 'ADDRESS#'
elif self.state == 'ADDRESS#':
self.handle_bit(b)
if len(self.data) == 16:
- self.state = 'COMMAND' if self.data_ok(True) else 'IDLE'
+ self.state = 'COMMAND' if self.data_ok(True, 8) else 'IDLE'
elif self.state == 'COMMAND':
self.handle_bit(b)
if len(self.data) == 8:
- self.data_ok(False)
+ self.data_ok(False, 8)
self.state = 'COMMAND#'
elif self.state == 'COMMAND#':
self.handle_bit(b)
if len(self.data) == 16:
- self.state = 'STOP' if self.data_ok(True) else 'IDLE'
+ self.state = 'STOP' if self.data_ok(True, 8) else 'IDLE'
elif self.state == 'STOP':
self.putstop(self.ss_bit)
self.putremote()