13 static const char *
const TAG =
"i2c.arduino";
18 #if defined(USE_ESP32) 19 static uint8_t next_bus_num = 0;
20 if (next_bus_num == 0) {
23 wire_ =
new TwoWire(next_bus_num);
26 #elif defined(USE_ESP8266) 28 #elif defined(USE_RP2040) 29 static bool first =
true;
48 ESP_LOGV(TAG,
"Scanning i2c bus for active devices...");
53 ESP_LOGCONFIG(TAG,
"I2C Bus:");
54 ESP_LOGCONFIG(TAG,
" SDA Pin: GPIO%u", this->
sda_pin_);
55 ESP_LOGCONFIG(TAG,
" SCL Pin: GPIO%u", this->
scl_pin_);
56 ESP_LOGCONFIG(TAG,
" Frequency: %u Hz", this->
frequency_);
57 switch (this->recovery_result_) {
59 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
62 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
65 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
69 ESP_LOGI(TAG,
"Results from i2c bus scan:");
71 ESP_LOGI(TAG,
"Found no i2c devices!");
75 ESP_LOGI(TAG,
"Found i2c device at address 0x%02X", s.first);
77 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
88 ESP_LOGVV(TAG,
"i2c bus not initialized!");
91 size_t to_request = 0;
92 for (
size_t i = 0; i < cnt; i++)
93 to_request += buffers[i].
len;
94 size_t ret =
wire_->requestFrom((
int) address, (
int) to_request, 1);
95 if (ret != to_request) {
96 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", to_request, address, ret);
100 for (
size_t i = 0; i < cnt; i++) {
101 const auto &buf = buffers[i];
102 for (
size_t j = 0; j < buf.len; j++)
106 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 108 std::string debug_hex;
110 for (
size_t i = 0; i < cnt; i++) {
111 const auto &buf = buffers[i];
112 for (
size_t j = 0; j < buf.len; j++) {
113 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
114 debug_hex += debug_buf;
117 ESP_LOGVV(TAG,
"0x%02X RX %s", address, debug_hex.c_str());
126 ESP_LOGVV(TAG,
"i2c bus not initialized!");
130 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 132 std::string debug_hex;
134 for (
size_t i = 0; i < cnt; i++) {
135 const auto &buf = buffers[i];
136 for (
size_t j = 0; j < buf.len; j++) {
137 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
138 debug_hex += debug_buf;
141 ESP_LOGVV(TAG,
"0x%02X TX %s", address, debug_hex.c_str());
144 wire_->beginTransmission(address);
146 for (
size_t i = 0; i < cnt; i++) {
147 const auto &buf = buffers[i];
150 size_t ret =
wire_->write(buf.data, buf.len);
152 if (ret != buf.len) {
153 ESP_LOGVV(TAG,
"TX failed at %u", written);
163 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
167 ESP_LOGVV(TAG,
"TX failed: not acknowledged");
170 ESP_LOGVV(TAG,
"TX failed: timeout");
174 ESP_LOGVV(TAG,
"TX failed: unknown error %u", status);
182 void ArduinoI2CBus::recover_() {
183 ESP_LOGI(TAG,
"Performing I2C bus recovery");
189 const auto half_period_usec = 1000000 / 100000 / 2;
199 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the I2C bus");
217 for (
auto i = 0; i < 9; i++) {
236 while (wait-- && digitalRead(
scl_pin_) == LOW) {
241 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
256 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
291 #endif // USE_ESP_IDF
std::vector< std::pair< uint8_t, bool > > scan_results_
void dump_config() override
Application App
Global storage of Application pointer - only one Application can exist.
ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t cnt, bool stop) override
ErrorCode readv(uint8_t address, ReadBuffer *buffers, size_t cnt) override
Implementation of SPI Controller mode.
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)