ESPHome  2023.5.5
coolix_protocol.cpp
Go to the documentation of this file.
1 #include "coolix_protocol.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace remote_base {
6 
7 static const char *const TAG = "remote.coolix";
8 
9 static const int32_t TICK_US = 560;
10 static const int32_t HEADER_MARK_US = 8 * TICK_US;
11 static const int32_t HEADER_SPACE_US = 8 * TICK_US;
12 static const int32_t BIT_MARK_US = 1 * TICK_US;
13 static const int32_t BIT_ONE_SPACE_US = 3 * TICK_US;
14 static const int32_t BIT_ZERO_SPACE_US = 1 * TICK_US;
15 static const int32_t FOOTER_MARK_US = 1 * TICK_US;
16 static const int32_t FOOTER_SPACE_US = 10 * TICK_US;
17 
18 static void encode_data(RemoteTransmitData *dst, const CoolixData &src) {
19  // Break data into bytes, starting at the Most Significant
20  // Byte. Each byte then being sent normal, then followed inverted.
21  for (unsigned shift = 16;; shift -= 8) {
22  // Grab a bytes worth of data.
23  const uint8_t byte = src >> shift;
24  // Normal
25  for (uint8_t mask = 1 << 7; mask; mask >>= 1)
26  dst->item(BIT_MARK_US, (byte & mask) ? BIT_ONE_SPACE_US : BIT_ZERO_SPACE_US);
27  // Inverted
28  for (uint8_t mask = 1 << 7; mask; mask >>= 1)
29  dst->item(BIT_MARK_US, (byte & mask) ? BIT_ZERO_SPACE_US : BIT_ONE_SPACE_US);
30  // Data end
31  if (shift == 0)
32  break;
33  }
34 }
35 
37  dst->set_carrier_frequency(38000);
38  dst->reserve(2 + 2 * 48 + 2 + 2 + 2 * 48 + 1);
39  dst->item(HEADER_MARK_US, HEADER_SPACE_US);
40  encode_data(dst, data);
41  dst->item(FOOTER_MARK_US, FOOTER_SPACE_US);
42  dst->item(HEADER_MARK_US, HEADER_SPACE_US);
43  encode_data(dst, data);
44  dst->mark(FOOTER_MARK_US);
45 }
46 
47 static bool decode_data(RemoteReceiveData &src, CoolixData &dst) {
48  uint32_t data = 0;
49  for (unsigned n = 3;; data <<= 8) {
50  // Read byte
51  for (uint32_t mask = 1 << 7; mask; mask >>= 1) {
52  if (!src.expect_mark(BIT_MARK_US))
53  return false;
54  if (src.expect_space(BIT_ONE_SPACE_US)) {
55  data |= mask;
56  } else if (!src.expect_space(BIT_ZERO_SPACE_US)) {
57  return false;
58  }
59  }
60  // Check for inverse byte
61  for (uint32_t mask = 1 << 7; mask; mask >>= 1) {
62  if (!src.expect_item(BIT_MARK_US, (data & mask) ? BIT_ZERO_SPACE_US : BIT_ONE_SPACE_US))
63  return false;
64  }
65  // Checking the end of reading
66  if (--n == 0) {
67  dst = data;
68  return true;
69  }
70  }
71 }
72 
74  CoolixData first, second;
75  if (data.expect_item(HEADER_MARK_US, HEADER_SPACE_US) && decode_data(data, first) &&
76  data.expect_item(FOOTER_MARK_US, FOOTER_SPACE_US) && data.expect_item(HEADER_MARK_US, HEADER_SPACE_US) &&
77  decode_data(data, second) && data.expect_mark(FOOTER_MARK_US) && first == second)
78  return first;
79  return {};
80 }
81 
82 void CoolixProtocol::dump(const CoolixData &data) { ESP_LOGD(TAG, "Received Coolix: 0x%06X", data); }
83 
84 } // namespace remote_base
85 } // namespace esphome
optional< CoolixData > decode(RemoteReceiveData data) override
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:31
void item(uint32_t mark, uint32_t space)
Definition: remote_base.h:24
void encode(RemoteTransmitData *dst, const CoolixData &data) override
void dump(const CoolixData &data) override
Definition: a4988.cpp:4
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.h:112