ESPHome  2024.12.2
magiquest_protocol.cpp
Go to the documentation of this file.
1 #include "magiquest_protocol.h"
2 #include "esphome/core/log.h"
3 
4 /* Based on protocol analysis from
5  * https://arduino-irremote.github.io/Arduino-IRremote/ir__MagiQuest_8cpp_source.html
6  */
7 
8 namespace esphome {
9 namespace remote_base {
10 
11 static const char *const TAG = "remote.magiquest";
12 
13 static const uint32_t MAGIQUEST_UNIT = 288; // us
14 static const uint32_t MAGIQUEST_ONE_MARK = 2 * MAGIQUEST_UNIT;
15 static const uint32_t MAGIQUEST_ONE_SPACE = 2 * MAGIQUEST_UNIT;
16 static const uint32_t MAGIQUEST_ZERO_MARK = MAGIQUEST_UNIT;
17 static const uint32_t MAGIQUEST_ZERO_SPACE = 3 * MAGIQUEST_UNIT;
18 
20  dst->reserve(101); // 2 start bits, 48 data bits, 1 stop bit
21  dst->set_carrier_frequency(38000);
22 
23  // 2 start bits
24  dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
25  dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
26  for (uint32_t mask = 1 << 31; mask; mask >>= 1) {
27  if (data.wand_id & mask) {
28  dst->item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE);
29  } else {
30  dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
31  }
32  }
33 
34  for (uint16_t mask = 1 << 15; mask; mask >>= 1) {
35  if (data.magnitude & mask) {
36  dst->item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE);
37  } else {
38  dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
39  }
40  }
41 
42  dst->mark(MAGIQUEST_UNIT);
43 }
45  MagiQuestData data{
46  .magnitude = 0,
47  .wand_id = 0,
48  };
49  // Two start bits
50  if (!src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE) ||
51  !src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
52  return {};
53  }
54 
55  for (uint32_t mask = 1 << 31; mask; mask >>= 1) {
56  if (src.expect_item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE)) {
57  data.wand_id |= mask;
58  } else if (src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
59  data.wand_id &= ~mask;
60  } else {
61  return {};
62  }
63  }
64 
65  for (uint16_t mask = 1 << 15; mask; mask >>= 1) {
66  if (src.expect_item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE)) {
67  data.magnitude |= mask;
68  } else if (src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
69  data.magnitude &= ~mask;
70  } else {
71  return {};
72  }
73  }
74 
75  src.expect_mark(MAGIQUEST_UNIT);
76  return data;
77 }
79  ESP_LOGI(TAG, "Received MagiQuest: wand_id=0x%08" PRIX32 ", magnitude=0x%04X", data.wand_id, data.magnitude);
80 }
81 
82 } // namespace remote_base
83 } // namespace esphome
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:34
void item(uint32_t mark, uint32_t space)
Definition: remote_base.h:29
optional< MagiQuestData > decode(RemoteReceiveData src) override
void dump(const MagiQuestData &data) override
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:74
void encode(RemoteTransmitData *dst, const MagiQuestData &data) override