[i2c] Use `i2c_master_probe` to scan i2c bus (#9831)

This commit is contained in:
Jesse Hills 2025-07-23 23:31:13 +12:00 committed by GitHub
parent bb6f8aeb94
commit babaa1db3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 18 additions and 6 deletions

View File

@ -94,7 +94,7 @@ class I2CBus {
protected: protected:
/// @brief Scans the I2C bus for devices. Devices presence is kept in an array of std::pair /// @brief Scans the I2C bus for devices. Devices presence is kept in an array of std::pair
/// that contains the address and the corresponding bool presence flag. /// that contains the address and the corresponding bool presence flag.
void i2c_scan_() { virtual void i2c_scan() {
for (uint8_t address = 8; address < 120; address++) { for (uint8_t address = 8; address < 120; address++) {
auto err = writev(address, nullptr, 0); auto err = writev(address, nullptr, 0);
if (err == ERROR_OK) { if (err == ERROR_OK) {

View File

@ -42,7 +42,7 @@ void ArduinoI2CBus::setup() {
this->initialized_ = true; this->initialized_ = true;
if (this->scan_) { if (this->scan_) {
ESP_LOGV(TAG, "Scanning bus for active devices"); ESP_LOGV(TAG, "Scanning bus for active devices");
this->i2c_scan_(); this->i2c_scan();
} }
} }

View File

@ -1,13 +1,13 @@
#ifdef USE_ESP_IDF #ifdef USE_ESP_IDF
#include "i2c_bus_esp_idf.h" #include "i2c_bus_esp_idf.h"
#include <driver/gpio.h>
#include <cinttypes> #include <cinttypes>
#include <cstring> #include <cstring>
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <driver/gpio.h>
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0) #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
#define SOC_HP_I2C_NUM SOC_I2C_NUM #define SOC_HP_I2C_NUM SOC_I2C_NUM
@ -78,7 +78,7 @@ void IDFI2CBus::setup() {
if (this->scan_) { if (this->scan_) {
ESP_LOGV(TAG, "Scanning for devices"); ESP_LOGV(TAG, "Scanning for devices");
this->i2c_scan_(); this->i2c_scan();
} }
#else #else
#if SOC_HP_I2C_NUM > 1 #if SOC_HP_I2C_NUM > 1
@ -125,7 +125,7 @@ void IDFI2CBus::setup() {
initialized_ = true; initialized_ = true;
if (this->scan_) { if (this->scan_) {
ESP_LOGV(TAG, "Scanning bus for active devices"); ESP_LOGV(TAG, "Scanning bus for active devices");
this->i2c_scan_(); this->i2c_scan();
} }
#endif #endif
} }
@ -167,6 +167,17 @@ void IDFI2CBus::dump_config() {
} }
} }
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
void IDFI2CBus::i2c_scan() {
for (uint8_t address = 8; address < 120; address++) {
auto err = i2c_master_probe(this->bus_, address, 20);
if (err == ESP_OK) {
this->scan_results_.emplace_back(address, true);
}
}
}
#endif
ErrorCode IDFI2CBus::readv(uint8_t address, ReadBuffer *buffers, size_t cnt) { ErrorCode IDFI2CBus::readv(uint8_t address, ReadBuffer *buffers, size_t cnt) {
// logging is only enabled with vv level, if warnings are shown the caller // logging is only enabled with vv level, if warnings are shown the caller
// should log them // should log them

View File

@ -2,9 +2,9 @@
#ifdef USE_ESP_IDF #ifdef USE_ESP_IDF
#include "esp_idf_version.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "i2c_bus.h" #include "i2c_bus.h"
#include "esp_idf_version.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2) #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
#include <driver/i2c_master.h> #include <driver/i2c_master.h>
#else #else
@ -46,6 +46,7 @@ class IDFI2CBus : public InternalI2CBus, public Component {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2) #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
i2c_master_dev_handle_t dev_; i2c_master_dev_handle_t dev_;
i2c_master_bus_handle_t bus_; i2c_master_bus_handle_t bus_;
void i2c_scan() override;
#endif #endif
i2c_port_t port_; i2c_port_t port_;
uint8_t sda_pin_; uint8_t sda_pin_;