ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
ds248x_one_wire_bus.cpp
Go to the documentation of this file.
2#include "ds248x.h"
3#include "esphome/core/log.h"
4
5namespace esphome::ds248x {
6
7static const char *const TAG = "ds248x.one_wire";
8
10 ESP_LOGCONFIG(TAG, "Setting up DS248x 1-Wire Bus (Channel %d)...", this->channel_);
11
12 // Parent setup happens in DS248xComponent::setup()
13 // We just need to scan for devices on this channel
14 if (!this->ensure_channel_()) {
15 ESP_LOGE(TAG, "Failed to select channel %d during setup", this->channel_);
16 this->mark_failed();
17 return;
18 }
19
20 // Perform device search on this channel
21 this->search();
22
23 ESP_LOGCONFIG(TAG, "Found %zu devices on channel %d", this->devices_.size(), this->channel_);
24}
25
27 ESP_LOGCONFIG(TAG, "DS248x 1-Wire Bus (Channel %d):", this->channel_);
28 this->dump_devices_(TAG);
29}
30
32 if (this->parent_ == nullptr) {
33 ESP_LOGE(TAG, "Parent not set!");
34 return false;
35 }
36 return this->parent_->select_channel(this->channel_);
37}
38
40 if (!this->ensure_channel_()) {
41 return -1;
42 }
43
44 bool presence = false;
45 if (!this->parent_->ow_reset(presence)) {
46 return -1;
47 }
48 return presence ? 1 : 0;
49}
50
52 if (!this->ensure_channel_()) {
53 return;
54 }
55 if (!this->parent_->ow_write_byte(val)) {
56 ESP_LOGE(TAG, "Failed to write byte 0x%02X on channel %d", val, this->channel_);
57 }
58}
59
61 if (!this->ensure_channel_()) {
62 return;
63 }
64 for (uint8_t i = 0; i < 8; i++) {
65 uint8_t byte = static_cast<uint8_t>(val >> (i * 8));
66 if (!this->parent_->ow_write_byte(byte)) {
67 ESP_LOGE(TAG, "Failed to write byte %d/8 (0x%02X) on channel %d - aborting write64", i + 1, byte, this->channel_);
68 return; // Stop writing to prevent sending corrupted data
69 }
70 }
71}
72
74 if (!this->ensure_channel_()) {
75 return 0;
76 }
77 uint8_t value = 0;
78 if (!this->parent_->ow_read_byte(value)) {
79 ESP_LOGE(TAG, "Failed to read byte on channel %d", this->channel_);
80 }
81 return value;
82}
83
85 if (!this->ensure_channel_()) {
86 return 0;
87 }
88 uint64_t value = 0;
89 for (uint8_t i = 0; i < 8; i++) {
90 uint8_t byte = 0;
91 if (!this->parent_->ow_read_byte(byte)) {
92 ESP_LOGE(TAG, "Failed to read byte %d/8 on channel %d - returning partial data", i + 1, this->channel_);
93 return value; // Return partial data to avoid blocking, caller should validate
94 }
95 value |= (static_cast<uint64_t>(byte) << (i * 8));
96 }
97 return value;
98}
99
101 this->search_last_discrepancy_ = 0;
102 this->search_last_device_flag_ = false;
103 this->search_address_ = 0;
104}
105
107 if (!this->ensure_channel_()) {
108 return 0;
109 }
110
111 if (this->search_last_device_flag_) {
112 return 0;
113 }
114
115 uint8_t last_zero = 0;
116 uint64_t address = this->search_address_;
117
118 // Iterate through all 64 bits
119 for (uint8_t bit_number = 1; bit_number <= 64; bit_number++) {
120 uint64_t bit_mask = 1ULL << (bit_number - 1);
121
122 // Determine search direction
123 bool search_direction;
124 if (bit_number < this->search_last_discrepancy_) {
125 search_direction = (address & bit_mask) != 0;
126 } else {
127 search_direction = (bit_number == this->search_last_discrepancy_);
128 }
129
130 // Perform triplet operation
131 uint8_t status = 0;
132 if (!this->parent_->search_triplet(search_direction, status)) {
133 ESP_LOGW(TAG, "1-Wire triplet failed at bit %d on channel %d - aborting search", bit_number, this->channel_);
134 this->reset_search();
135 return 0;
136 }
137
138 bool id_bit = (status & DS248X_STATUS_SBR) != 0;
139 bool cmp_id_bit = (status & DS248X_STATUS_TSB) != 0;
140 bool dir_taken = (status & DS248X_STATUS_DIR) != 0;
141
142 if (id_bit && cmp_id_bit) {
143 // No devices participating
144 this->reset_search();
145 return 0;
146 }
147
148 if (!id_bit && !cmp_id_bit && !dir_taken) {
149 // Discrepancy, went 0 - record position
150 last_zero = bit_number;
151 }
152
153 // Update address based on direction taken
154 if (dir_taken) {
155 address |= bit_mask;
156 } else {
157 address &= ~bit_mask;
158 }
159 }
160
161 // Search successful
162 this->search_last_discrepancy_ = last_zero;
163 if (last_zero == 0) {
164 this->search_last_device_flag_ = true;
165 }
166 this->search_address_ = address;
167
168 return address;
169}
170
171} // namespace esphome::ds248x
uint8_t address
Definition bl0906.h:4
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
bool select_channel(uint8_t channel)
Definition ds248x.cpp:194
bool ow_reset(bool &presence)
Definition ds248x.cpp:229
bool ow_read_byte(uint8_t &byte)
Definition ds248x.cpp:280
bool ow_write_byte(uint8_t byte)
Definition ds248x.cpp:257
bool search_triplet(bool search_direction, uint8_t &status)
Definition ds248x.cpp:300
void write64(uint64_t val) override
bool ensure_channel_()
Select the channel on the DS248x before any 1-Wire operation.
std::vector< uint64_t > devices_
void dump_devices_(const char *tag)
log the found devices
void search()
Search for 1-Wire devices on the bus.
mopeka_std_values val[3]