diff options
author | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-07-25 17:56:54 +0200 |
---|---|---|
committer | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-07-25 23:21:23 +0200 |
commit | 17e0ba228dadb7a12aa0e11fa81fcbc4a7836349 (patch) | |
tree | 9dbb186a5df732c292e48862525c0da0b5bb97e2 | |
parent | 025c728ed12e33121fb5be4ce14085afc2f23853 (diff) | |
download | libsigrokdecode-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.
-rw-r--r-- | decoders/ir_nec/__init__.py | 1 | ||||
-rw-r--r-- | decoders/ir_nec/pd.py | 41 |
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() |