ESPHome  2024.11.0
canalsat_protocol.cpp
Go to the documentation of this file.
1 #include "canalsat_protocol.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace remote_base {
6 
7 static const char *const CANALSAT_TAG = "remote.canalsat";
8 static const char *const CANALSATLD_TAG = "remote.canalsatld";
9 
10 static const uint16_t CANALSAT_FREQ = 55500;
11 static const uint16_t CANALSATLD_FREQ = 56000;
12 static const uint16_t CANALSAT_UNIT = 250;
13 static const uint16_t CANALSATLD_UNIT = 320;
14 
16  this->frequency_ = CANALSAT_FREQ;
17  this->unit_ = CANALSAT_UNIT;
18  this->tag_ = CANALSAT_TAG;
19 }
20 
22  this->frequency_ = CANALSATLD_FREQ;
23  this->unit_ = CANALSATLD_UNIT;
24  this->tag_ = CANALSATLD_TAG;
25 }
26 
28  dst->reserve(48);
30 
31  uint32_t raw{
32  static_cast<uint32_t>((1 << 23) | (data.device << 16) | (data.address << 10) | (0 << 9) | (data.command << 1))};
33  bool was_high{true};
34 
35  for (uint32_t mask = 0x800000; mask; mask >>= 1) {
36  if (raw & mask) {
37  if (was_high) {
38  dst->mark(this->unit_);
39  }
40  was_high = true;
41  if (raw & mask >> 1) {
42  dst->space(this->unit_);
43  } else {
44  dst->space(this->unit_ * 2);
45  }
46  } else {
47  if (!was_high) {
48  dst->space(this->unit_);
49  }
50  was_high = false;
51  if (raw & mask >> 1) {
52  dst->mark(this->unit_ * 2);
53  } else {
54  dst->mark(this->unit_);
55  }
56  }
57  }
58 }
59 
61  CanalSatData data{
62  .device = 0,
63  .address = 0,
64  .repeat = 0,
65  .command = 0,
66  };
67 
68  // Check if initial mark and spaces match
69  if (!src.peek_mark(this->unit_) || !(src.peek_space(this->unit_, 1) || src.peek_space(this->unit_ * 2, 1))) {
70  return {};
71  }
72 
73  uint8_t bit{1};
74  uint8_t offset{1};
75  uint32_t buffer{0};
76 
77  while (offset < 24) {
78  buffer = buffer | (bit << (24 - offset++));
79  src.advance();
80  if (src.peek_mark(this->unit_) || src.peek_space(this->unit_)) {
81  src.advance();
82  } else if (src.peek_mark(this->unit_ * 2) || src.peek_space(this->unit_ * 2)) {
83  bit = !bit;
84  } else if (offset != 24 && bit != 1) { // If last bit is high, final space is indistinguishable
85  return {};
86  }
87  }
88 
89  data.device = (0xFF0000 & buffer) >> 16;
90  data.address = (0x00FF00 & buffer) >> 10;
91  data.repeat = (0x00FF00 & buffer) >> 9;
92  data.command = (0x0000FF & buffer) >> 1;
93 
94  return data;
95 }
96 
98  if (this->tag_ == CANALSATLD_TAG) {
99  ESP_LOGI(this->tag_, "Received CanalSatLD: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
100  data.address, data.command, data.repeat);
101  } else {
102  ESP_LOGI(this->tag_, "Received CanalSat: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
103  data.address, data.command, data.repeat);
104  }
105 }
106 
107 } // namespace remote_base
108 } // namespace esphome
uint8_t raw[35]
Definition: bl0939.h:19
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
void encode(RemoteTransmitData *dst, const CanalSatData &data) override
optional< CanalSatData > decode(RemoteReceiveData src) override
bool peek_mark(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:34
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void advance(uint32_t amount=1)
Definition: remote_base.h:70
void dump(const CanalSatData &data) override