From 04e6f475b4f0d0fd9923b0dc6a1ff60ad2eb2ecd Mon Sep 17 00:00:00 2001 From: Lukas Klass Date: Fri, 19 Jun 2020 00:50:58 +0200 Subject: [PATCH] Fix decode and encode for RC5-protocol (#1047) * Fix receive and transmit for RC5-protocol Receive did not work as a sequence of two high or low puleses are detected as one long pulse. Transmit was extended to respect the field bit in order to enable codes up to 127. * Fix code formatting --- esphome/components/remote_base/__init__.py | 2 +- .../components/remote_base/rc5_protocol.cpp | 46 +++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index 05a3e7e1aa..770394faec 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -420,7 +420,7 @@ def raw_action(var, config, args): RC5Data, RC5BinarySensor, RC5Trigger, RC5Action, RC5Dumper = declare_protocol('RC5') RC5_SCHEMA = cv.Schema({ cv.Required(CONF_ADDRESS): cv.All(cv.hex_int, cv.Range(min=0, max=0x1F)), - cv.Required(CONF_COMMAND): cv.All(cv.hex_int, cv.Range(min=0, max=0x3F)), + cv.Required(CONF_COMMAND): cv.All(cv.hex_int, cv.Range(min=0, max=0x7F)), }) diff --git a/esphome/components/remote_base/rc5_protocol.cpp b/esphome/components/remote_base/rc5_protocol.cpp index 35bff588e9..a6165492ac 100644 --- a/esphome/components/remote_base/rc5_protocol.cpp +++ b/esphome/components/remote_base/rc5_protocol.cpp @@ -14,10 +14,16 @@ void RC5Protocol::encode(RemoteTransmitData *dst, const RC5Data &data) { dst->set_carrier_frequency(36000); uint64_t out_data = 0; - out_data |= 0b11 << 12; + uint8_t command = data.command; + if (data.command >= 64) { + out_data |= 0b10 << 12; + command = command - 64; + } else { + out_data |= 0b11 << 12; + } out_data |= TOGGLE << 11; out_data |= data.address << 6; - out_data |= data.command; + out_data |= command; for (uint64_t mask = 1UL << (NBITS - 1); mask != 0; mask >>= 1) { if (out_data & mask) { @@ -35,22 +41,44 @@ optional RC5Protocol::decode(RemoteReceiveData src) { .address = 0, .command = 0, }; - src.expect_space(BIT_TIME_US); - if (!src.expect_mark(BIT_TIME_US) || !src.expect_space(BIT_TIME_US) || !src.expect_mark(BIT_TIME_US)) + int field_bit = 0; + + if (src.expect_space(BIT_TIME_US) && src.expect_mark(BIT_TIME_US)) { + field_bit = 1; + } else if (src.expect_space(2 * BIT_TIME_US)) { + field_bit = 0; + } else { return {}; + } + + if (!(((src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US)) || + (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US))) && + (((src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) && + (src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US))) || + ((src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) && + (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US)))))) { + return {}; + } uint64_t out_data = 0; - for (int bit = NBITS - 3; bit >= 0; bit--) { - if (src.expect_space(BIT_TIME_US) && src.expect_mark(BIT_TIME_US)) { - out_data |= 1 << bit; - } else if (src.expect_mark(BIT_TIME_US) && src.expect_space(BIT_TIME_US)) { + for (int bit = NBITS - 4; bit >= 1; bit--) { + if ((src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) && + (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US))) { out_data |= 0 << bit; + } else if ((src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) && + (src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US))) { + out_data |= 1 << bit; } else { return {}; } } + if (src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) { + out_data |= 0; + } else if (src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) { + out_data |= 1; + } - out.command = out_data & 0x3F; + out.command = (out_data & 0x3F) + (1 - field_bit) * 64; out.address = (out_data >> 6) & 0x1F; return out; }