ESPHome  2024.12.2
one_wire_bus.cpp
Go to the documentation of this file.
1 #include "one_wire_bus.h"
2 #include "esphome/core/helpers.h"
3 
4 namespace esphome {
5 namespace one_wire {
6 
7 static const char *const TAG = "one_wire";
8 
9 static const uint8_t DALLAS_MODEL_DS18S20 = 0x10;
10 static const uint8_t DALLAS_MODEL_DS1822 = 0x22;
11 static const uint8_t DALLAS_MODEL_DS18B20 = 0x28;
12 static const uint8_t DALLAS_MODEL_DS1825 = 0x3B;
13 static const uint8_t DALLAS_MODEL_DS28EA00 = 0x42;
14 
15 const uint8_t ONE_WIRE_ROM_SELECT = 0x55;
16 const uint8_t ONE_WIRE_ROM_SEARCH = 0xF0;
17 
18 const std::vector<uint64_t> &OneWireBus::get_devices() { return this->devices_; }
19 
20 bool IRAM_ATTR OneWireBus::select(uint64_t address) {
21  if (!this->reset())
22  return false;
23  this->write8(ONE_WIRE_ROM_SELECT);
24  this->write64(address);
25  return true;
26 }
27 
29  this->devices_.clear();
30 
31  this->reset_search();
32  uint64_t address;
33  while (true) {
34  {
35  InterruptLock lock;
36  if (!this->reset()) {
37  // Reset failed or no devices present
38  return;
39  }
40 
41  this->write8(ONE_WIRE_ROM_SEARCH);
42  address = this->search_int();
43  }
44  if (address == 0)
45  break;
46  auto *address8 = reinterpret_cast<uint8_t *>(&address);
47  if (crc8(address8, 7) != address8[7]) {
48  ESP_LOGW(TAG, "Dallas device 0x%s has invalid CRC.", format_hex(address).c_str());
49  } else {
50  this->devices_.push_back(address);
51  }
52  }
53 }
54 
56  this->write8(0xCC); // skip ROM
57 }
58 
59 const LogString *OneWireBus::get_model_str(uint8_t model) {
60  switch (model) {
61  case DALLAS_MODEL_DS18S20:
62  return LOG_STR("DS18S20");
63  case DALLAS_MODEL_DS1822:
64  return LOG_STR("DS1822");
65  case DALLAS_MODEL_DS18B20:
66  return LOG_STR("DS18B20");
67  case DALLAS_MODEL_DS1825:
68  return LOG_STR("DS1825");
69  case DALLAS_MODEL_DS28EA00:
70  return LOG_STR("DS28EA00");
71  default:
72  return LOG_STR("Unknown");
73  }
74 }
75 
76 void OneWireBus::dump_devices_(const char *tag) {
77  if (this->devices_.empty()) {
78  ESP_LOGW(tag, " Found no devices!");
79  } else {
80  ESP_LOGCONFIG(tag, " Found devices:");
81  for (auto &address : this->devices_) {
82  ESP_LOGCONFIG(tag, " 0x%s (%s)", format_hex(address).c_str(), LOG_STR_ARG(get_model_str(address & 0xff)));
83  }
84  }
85 }
86 
87 } // namespace one_wire
88 } // namespace esphome
void skip()
Write a command to the bus that addresses all devices by skipping the ROM.
virtual void write64(uint64_t val)=0
Write a 64 bit unsigned integer to the bus. LSB first.
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
Definition: helpers.cpp:357
const uint8_t ONE_WIRE_ROM_SEARCH
virtual void reset_search()=0
Reset the device search.
virtual bool reset()=0
Reset the bus, should be done before all write operations.
bool select(uint64_t address)
Select a specific address on the bus for the following command.
void search()
Search for 1-Wire devices on the bus.
void dump_devices_(const char *tag)
log the found devices
const uint8_t ONE_WIRE_ROM_SELECT
const LogString * get_model_str(uint8_t model)
Get the description string for this model.
uint8_t crc8(const uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum of data with size len.
Definition: helpers.cpp:95
const std::vector< uint64_t > & get_devices()
Return the list of found devices.
virtual void write8(uint8_t val)=0
Write a word to the bus. LSB first.
Helper class to disable interrupts.
Definition: helpers.h:606
virtual uint64_t search_int()=0
Search for a 1-Wire device on the bus. Returns 0 if all devices have been found.
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
uint8_t address
Definition: bl0906.h:211
std::vector< uint64_t > devices_
Definition: one_wire_bus.h:48