ESPHome  2024.11.0
rc5_protocol.cpp
Go to the documentation of this file.
1 #include "rc5_protocol.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace remote_base {
6 
7 static const char *const TAG = "remote.rc5";
8 
9 static const uint32_t BIT_TIME_US = 889;
10 static const uint8_t NBITS = 14;
11 
13  static bool toggle = false;
14  dst->set_carrier_frequency(36000);
15 
16  uint64_t out_data = 0;
17  uint8_t command = data.command;
18  if (data.command >= 64) {
19  out_data |= 0b10 << 12;
20  command = command - 64;
21  } else {
22  out_data |= 0b11 << 12;
23  }
24  out_data |= toggle << 11;
25  out_data |= data.address << 6;
26  out_data |= command;
27 
28  for (uint64_t mask = 1UL << (NBITS - 1); mask != 0; mask >>= 1) {
29  if (out_data & mask) {
30  dst->space(BIT_TIME_US);
31  dst->mark(BIT_TIME_US);
32  } else {
33  dst->mark(BIT_TIME_US);
34  dst->space(BIT_TIME_US);
35  }
36  }
37  toggle = !toggle;
38 }
40  RC5Data out{
41  .address = 0,
42  .command = 0,
43  };
44  uint8_t field_bit;
45 
46  if (src.expect_space(BIT_TIME_US) && src.expect_mark(BIT_TIME_US)) {
47  field_bit = 1;
48  } else if (src.expect_space(2 * BIT_TIME_US)) {
49  field_bit = 0;
50  } else {
51  return {};
52  }
53 
54  if (!(((src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US)) ||
55  (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US))) &&
56  (((src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) &&
57  (src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US))) ||
58  ((src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) &&
59  (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US)))))) {
60  return {};
61  }
62 
63  uint32_t out_data = 0;
64  for (int bit = NBITS - 4; bit >= 1; bit--) {
65  if ((src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) &&
66  (src.expect_mark(BIT_TIME_US) || src.peek_mark(2 * BIT_TIME_US))) {
67  out_data |= 0 << bit;
68  } else if ((src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) &&
69  (src.expect_space(BIT_TIME_US) || src.peek_space(2 * BIT_TIME_US))) {
70  out_data |= 1 << bit;
71  } else {
72  return {};
73  }
74  }
75  if (src.expect_space(BIT_TIME_US) || src.expect_space(2 * BIT_TIME_US)) {
76  out_data |= 0;
77  } else if (src.expect_mark(BIT_TIME_US) || src.expect_mark(2 * BIT_TIME_US)) {
78  out_data |= 1;
79  }
80 
81  out.command = (uint8_t) (out_data & 0x3F) + (1 - field_bit) * 64u;
82  out.address = (out_data >> 6) & 0x1F;
83  return out;
84 }
85 void RC5Protocol::dump(const RC5Data &data) {
86  ESP_LOGI(TAG, "Received RC5: address=0x%02X, command=0x%02X", data.address, data.command);
87 }
88 
89 } // namespace remote_base
90 } // namespace esphome
void encode(RemoteTransmitData *dst, const RC5Data &data) override
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:34
bool peek_space(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:43
optional< RC5Data > decode(RemoteReceiveData src) override
bool peek_mark(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:34
void dump(const RC5Data &data) override
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7