ESPHome 2026.5.1
Loading...
Searching...
No Matches
pioneer_protocol.cpp
Go to the documentation of this file.
1#include "pioneer_protocol.h"
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6static const char *const TAG = "remote.pioneer";
7
8static constexpr uint32_t HEADER_HIGH_US = 9000;
9static constexpr uint32_t HEADER_LOW_US = 4500;
10static constexpr uint32_t BIT_HIGH_US = 560;
11static constexpr uint32_t BIT_ONE_LOW_US = 1690;
12static constexpr uint32_t BIT_ZERO_LOW_US = 560;
13static constexpr uint32_t TRAILER_SPACE_US = 25500;
14
16 uint32_t address1 = ((data.rc_code_1 & 0xff00) | (~(data.rc_code_1 >> 8) & 0xff));
17 uint32_t address2 = ((data.rc_code_2 & 0xff00) | (~(data.rc_code_2 >> 8) & 0xff));
18 uint32_t command1 = 0;
19 uint32_t command2 = 0;
20
21 for (uint32_t bit = 0; bit < 4; bit++) {
22 if ((data.rc_code_1 >> bit) & 1)
23 command1 |= (1UL << (7 - bit));
24 }
25
26 for (uint32_t bit = 0; bit < 4; bit++) {
27 if ((data.rc_code_1 >> (bit + 4)) & 1)
28 command1 |= (1UL << (3 - bit));
29 }
30
31 for (uint32_t bit = 0; bit < 4; bit++) {
32 if ((data.rc_code_2 >> bit) & 1)
33 command2 |= (1UL << (7 - bit));
34 }
35
36 for (uint32_t bit = 0; bit < 4; bit++) {
37 if ((data.rc_code_2 >> (bit + 4)) & 1)
38 command2 |= (1UL << (3 - bit));
39 }
40
41 command1 = (command1 << 8) | ((~command1) & 0xff);
42 command2 = (command2 << 8) | ((~command2) & 0xff);
43
44 if (data.rc_code_2 == 0) {
45 dst->reserve(68);
46 } else {
47 dst->reserve((68 * 2) + 1);
48 }
49
50 dst->set_carrier_frequency(40000);
51
52 dst->item(HEADER_HIGH_US, HEADER_LOW_US);
53 for (uint32_t mask = 1UL << 15; mask; mask >>= 1) {
54 if (address1 & mask) {
55 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
56 } else {
57 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
58 }
59 }
60
61 for (uint32_t mask = 1UL << 15; mask; mask >>= 1) {
62 if (command1 & mask) {
63 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
64 } else {
65 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
66 }
67 }
68
69 dst->mark(BIT_HIGH_US);
70
71 if (data.rc_code_2 != 0) {
72 dst->space(TRAILER_SPACE_US);
73 dst->item(HEADER_HIGH_US, HEADER_LOW_US);
74 for (uint32_t mask = 1UL << 15; mask; mask >>= 1) {
75 if (address2 & mask) {
76 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
77 } else {
78 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
79 }
80 }
81
82 for (uint32_t mask = 1UL << 15; mask; mask >>= 1) {
83 if (command2 & mask) {
84 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
85 } else {
86 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
87 }
88 }
89
90 dst->mark(BIT_HIGH_US);
91 }
92}
93optional<PioneerData> PioneerProtocol::decode(RemoteReceiveData src) {
94 uint16_t address1 = 0;
95 uint16_t command1 = 0;
96
97 PioneerData data{
98 .rc_code_1 = 0,
99 .rc_code_2 = 0,
100 };
101 if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
102 return {};
103
104 for (uint32_t mask = 1UL << 15; mask != 0; mask >>= 1) {
105 if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
106 address1 |= mask;
107 } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
108 address1 &= ~mask;
109 } else {
110 return {};
111 }
112 }
113
114 for (uint32_t mask = 1UL << 15; mask != 0; mask >>= 1) {
115 if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
116 command1 |= mask;
117 } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
118 command1 &= ~mask;
119 } else {
120 return {};
121 }
122 }
123
124 if (!src.expect_mark(BIT_HIGH_US))
125 return {};
126
127 if ((address1 >> 8) != ((~address1) & 0xff))
128 return {};
129
130 if ((command1 >> 8) != ((~command1) & 0xff))
131 return {};
132
133 for (uint32_t bit = 0; bit < 4; bit++) {
134 if ((~command1 >> bit) & 1)
135 data.rc_code_1 |= (1UL << (7 - bit));
136 }
137
138 for (uint32_t bit = 0; bit < 4; bit++) {
139 if ((~command1 >> (bit + 4)) & 1)
140 data.rc_code_1 |= (1UL << (3 - bit));
141 }
142 data.rc_code_1 |= address1 & 0xff00;
143
144 return data;
145}
147 if (data.rc_code_2 == 0) {
148 ESP_LOGI(TAG, "Received Pioneer: rc_code_X=0x%04X", data.rc_code_1);
149 } else {
150 ESP_LOGI(TAG, "Received Pioneer: rc_code_1=0x%04X, rc_code_2=0x%04X", data.rc_code_1, data.rc_code_2);
151 }
152}
153
154} // namespace esphome::remote_base
void dump(const PioneerData &data) override
void encode(RemoteTransmitData *dst, const PioneerData &data) override
optional< PioneerData > decode(RemoteReceiveData src) override
bool expect_item(uint32_t mark, uint32_t space)
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:29
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:24
static void uint32_t