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