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