ESPHome 2025.7.2
Loading...
Searching...
No Matches
ds2484.cpp
Go to the documentation of this file.
1#include "ds2484.h"
2
3namespace esphome {
4namespace ds2484 {
5static const char *const TAG = "ds2484.onewire";
6
8 ESP_LOGCONFIG(TAG, "Running setup");
9 this->reset_device();
10 this->search();
11}
12
14 ESP_LOGCONFIG(TAG, "1-wire bus:");
15 this->dump_devices_(TAG);
16}
17
18bool DS2484OneWireBus::read_status_(uint8_t *status) {
19 for (uint8_t retry_nr = 0; retry_nr < 10; retry_nr++) {
20 if (this->read(status, 1) != i2c::ERROR_OK) {
21 ESP_LOGE(TAG, "read status error");
22 return false;
23 }
24 ESP_LOGVV(TAG, "status: %02x", *status);
25 if (!(*status & 1)) {
26 return true;
27 }
28 }
29 ESP_LOGE(TAG, "read status error: too many retries");
30 return false;
31}
32
34 uint8_t status;
35 return this->read_status_(&status);
36}
37
39 ESP_LOGVV(TAG, "reset_device");
40 uint8_t device_reset_cmd = 0xf0;
41 uint8_t response;
42 if (this->write(&device_reset_cmd, 1) != i2c::ERROR_OK) {
43 return false;
44 }
45 if (!this->wait_for_completion_()) {
46 ESP_LOGE(TAG, "reset_device: can't complete");
47 return false;
48 }
49 uint8_t config = (this->active_pullup_ ? 1 : 0) | (this->strong_pullup_ ? 4 : 0);
50 uint8_t write_config[2] = {0xd2, (uint8_t) (config | (~config << 4))};
51 if (this->write(write_config, 2) != i2c::ERROR_OK) {
52 ESP_LOGE(TAG, "reset_device: can't write config");
53 return false;
54 }
55 if (this->read(&response, 1) != i2c::ERROR_OK) {
56 ESP_LOGE(TAG, "can't read read8 response");
57 return false;
58 }
59 if (response != (write_config[1] & 0xf)) {
60 ESP_LOGE(TAG, "configuration didn't update");
61 return false;
62 }
63 return true;
64};
65
67 ESP_LOGVV(TAG, "reset");
68 uint8_t reset_cmd = 0xb4;
69 if (this->write(&reset_cmd, 1) != i2c::ERROR_OK) {
70 return -1;
71 }
72 return this->wait_for_completion_() ? 1 : 0;
73};
74
75void DS2484OneWireBus::write8_(uint8_t value) {
76 uint8_t buffer[2] = {0xa5, value};
77 this->write(buffer, 2);
79};
80
81void DS2484OneWireBus::write8(uint8_t value) {
82 ESP_LOGVV(TAG, "write8: %02x", value);
83 this->write8_(value);
84};
85
86void DS2484OneWireBus::write64(uint64_t value) {
87 ESP_LOGVV(TAG, "write64: %llx", value);
88 for (uint8_t i = 0; i < 8; i++) {
89 this->write8_((value >> (i * 8)) & 0xff);
90 }
91}
92
94 uint8_t read8_cmd = 0x96;
95 uint8_t set_read_reg_cmd[2] = {0xe1, 0xe1};
96 uint8_t response = 0;
97 if (this->write(&read8_cmd, 1) != i2c::ERROR_OK) {
98 ESP_LOGE(TAG, "can't write read8 cmd");
99 return 0;
100 }
101 this->wait_for_completion_();
102 if (this->write(set_read_reg_cmd, 2) != i2c::ERROR_OK) {
103 ESP_LOGE(TAG, "can't set read data reg");
104 return 0;
105 }
106 if (this->read(&response, 1) != i2c::ERROR_OK) {
107 ESP_LOGE(TAG, "can't read read8 response");
108 return 0;
109 }
110 return response;
111}
112
114 uint8_t response = 0;
115 for (uint8_t i = 0; i < 8; i++) {
116 response |= (this->read8() << (i * 8));
117 }
118 return response;
119}
120
122 this->last_discrepancy_ = 0;
123 this->last_device_flag_ = false;
124 this->address_ = 0;
125}
126
127bool DS2484OneWireBus::one_wire_triple_(bool *branch, bool *id_bit, bool *cmp_id_bit) {
128 uint8_t buffer[2] = {(uint8_t) 0x78, (uint8_t) (*branch ? 0x80u : 0)};
129 uint8_t status;
130 if (!this->read_status_(&status)) {
131 ESP_LOGE(TAG, "one_wire_triple start: read status error");
132 return false;
133 }
134 if (this->write(buffer, 2) != i2c::ERROR_OK) {
135 ESP_LOGV(TAG, "one_wire_triple: can't write cmd");
136 return false;
137 }
138 if (!this->read_status_(&status)) {
139 ESP_LOGE(TAG, "one_wire_triple: read status error");
140 return false;
141 }
142 *id_bit = bool(status & 0x20);
143 *cmp_id_bit = bool(status & 0x40);
144 *branch = bool(status & 0x80);
145 return true;
146}
147
148uint64_t IRAM_ATTR DS2484OneWireBus::search_int() {
149 ESP_LOGVV(TAG, "search_int");
150 if (this->last_device_flag_) {
151 ESP_LOGVV(TAG, "last device flag set, quitting");
152 return 0u;
153 }
154
155 uint8_t last_zero = 0;
156 uint64_t bit_mask = 1;
157 uint64_t address = this->address_;
158
159 // Initiate search
160 for (uint8_t bit_number = 1; bit_number <= 64; bit_number++, bit_mask <<= 1) {
161 bool branch;
162
163 // compute branch value for the case when there is a discrepancy
164 // (there are devices with both 0s and 1s at this bit)
165 if (bit_number < this->last_discrepancy_) {
166 branch = (address & bit_mask) > 0;
167 } else {
168 branch = bit_number == this->last_discrepancy_;
169 }
170
171 bool id_bit, cmp_id_bit;
172 bool branch_before = branch;
173 if (!this->one_wire_triple_(&branch, &id_bit, &cmp_id_bit)) {
174 ESP_LOGW(TAG, "one wire triple error, quitting");
175 return 0;
176 }
177
178 if (id_bit && cmp_id_bit) {
179 ESP_LOGW(TAG, "no devices on the bus, quitting");
180 // No devices participating in search
181 return 0;
182 }
183
184 if (!id_bit && !cmp_id_bit && !branch) {
185 last_zero = bit_number;
186 }
187
188 ESP_LOGVV(TAG, "%d %d branch: %d %d", id_bit, cmp_id_bit, branch_before, branch);
189
190 if (branch) {
191 address |= bit_mask;
192 } else {
193 address &= ~bit_mask;
194 }
195 }
196 ESP_LOGVV(TAG, "last_discepancy: %d", last_zero);
197 ESP_LOGVV(TAG, "address: %llx", address);
198 this->last_discrepancy_ = last_zero;
199 if (this->last_discrepancy_ == 0) {
200 // we're at root and have no choices left, so this was the last one.
201 this->last_device_flag_ = true;
202 }
203
204 this->address_ = address;
205 return address;
206}
207
208} // namespace ds2484
209} // namespace esphome
uint8_t address
Definition bl0906.h:4
uint8_t status
Definition bl0942.h:8
void write8(uint8_t) override
Definition ds2484.cpp:81
bool one_wire_triple_(bool *branch, bool *id_bit, bool *cmp_id_bit)
Definition ds2484.cpp:127
uint64_t search_int() override
Definition ds2484.cpp:148
void write64(uint64_t) override
Definition ds2484.cpp:86
uint64_t read64() override
Definition ds2484.cpp:113
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition i2c.h:190
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition i2c.h:164
void dump_devices_(const char *tag)
log the found devices
void search()
Search for 1-Wire devices on the bus.
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7