1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-10 23:32:23 +01:00

[i2c] Perform register reads as single transactions (#10389)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Clyde Stubbs
2025-08-27 19:30:33 +10:00
committed by Jesse Hills
parent b6bb6699d1
commit 4ab37b069b
38 changed files with 329 additions and 643 deletions

View File

@@ -1,4 +1,6 @@
#include "i2c.h"
#include "esphome/core/defines.h"
#include "esphome/core/log.h"
#include <memory>
@@ -7,38 +9,48 @@ namespace i2c {
static const char *const TAG = "i2c";
ErrorCode I2CDevice::read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop) {
ErrorCode err = this->write(&a_register, 1, stop);
if (err != ERROR_OK)
return err;
return bus_->read(address_, data, len);
void I2CBus::i2c_scan_() {
// suppress logs from the IDF I2C library during the scan
#if defined(USE_ESP32) && defined(USE_LOGGER)
auto previous = esp_log_level_get("*");
esp_log_level_set("*", ESP_LOG_NONE);
#endif
for (uint8_t address = 8; address != 120; address++) {
auto err = write_readv(address, nullptr, 0, nullptr, 0);
if (err == ERROR_OK) {
scan_results_.emplace_back(address, true);
} else if (err == ERROR_UNKNOWN) {
scan_results_.emplace_back(address, false);
}
}
#if defined(USE_ESP32) && defined(USE_LOGGER)
esp_log_level_set("*", previous);
#endif
}
ErrorCode I2CDevice::read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop) {
ErrorCode I2CDevice::read_register(uint8_t a_register, uint8_t *data, size_t len) {
return bus_->write_readv(this->address_, &a_register, 1, data, len);
}
ErrorCode I2CDevice::read_register16(uint16_t a_register, uint8_t *data, size_t len) {
a_register = convert_big_endian(a_register);
ErrorCode const err = this->write(reinterpret_cast<const uint8_t *>(&a_register), 2, stop);
if (err != ERROR_OK)
return err;
return bus_->read(address_, data, len);
return bus_->write_readv(this->address_, reinterpret_cast<const uint8_t *>(&a_register), 2, data, len);
}
ErrorCode I2CDevice::write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop) {
WriteBuffer buffers[2];
buffers[0].data = &a_register;
buffers[0].len = 1;
buffers[1].data = data;
buffers[1].len = len;
return bus_->writev(address_, buffers, 2, stop);
ErrorCode I2CDevice::write_register(uint8_t a_register, const uint8_t *data, size_t len) const {
std::vector<uint8_t> v{};
v.push_back(a_register);
v.insert(v.end(), data, data + len);
return bus_->write_readv(this->address_, v.data(), v.size(), nullptr, 0);
}
ErrorCode I2CDevice::write_register16(uint16_t a_register, const uint8_t *data, size_t len, bool stop) {
a_register = convert_big_endian(a_register);
WriteBuffer buffers[2];
buffers[0].data = reinterpret_cast<const uint8_t *>(&a_register);
buffers[0].len = 2;
buffers[1].data = data;
buffers[1].len = len;
return bus_->writev(address_, buffers, 2, stop);
ErrorCode I2CDevice::write_register16(uint16_t a_register, const uint8_t *data, size_t len) const {
std::vector<uint8_t> v(len + 2);
v.push_back(a_register >> 8);
v.push_back(a_register);
v.insert(v.end(), data, data + len);
return bus_->write_readv(this->address_, v.data(), v.size(), nullptr, 0);
}
bool I2CDevice::read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len) {
@@ -49,7 +61,7 @@ bool I2CDevice::read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len) {
return true;
}
bool I2CDevice::write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) {
bool I2CDevice::write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const {
// we have to copy in order to be able to change byte order
std::unique_ptr<uint16_t[]> temp{new uint16_t[len]};
for (size_t i = 0; i < len; i++)