12 static const char *
const TAG =
"i2c.arduino";
17 #if defined(USE_ESP32) 18 static uint8_t next_bus_num = 0;
19 if (next_bus_num == 0) {
22 wire_ =
new TwoWire(next_bus_num);
25 #elif defined(USE_ESP8266) 27 #elif defined(USE_RP2040) 28 static bool first =
true;
47 ESP_LOGV(TAG,
"Scanning i2c bus for active devices...");
52 ESP_LOGCONFIG(TAG,
"I2C Bus:");
53 ESP_LOGCONFIG(TAG,
" SDA Pin: GPIO%u", this->
sda_pin_);
54 ESP_LOGCONFIG(TAG,
" SCL Pin: GPIO%u", this->
scl_pin_);
55 ESP_LOGCONFIG(TAG,
" Frequency: %u Hz", this->
frequency_);
56 switch (this->recovery_result_) {
58 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
61 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
64 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
68 ESP_LOGI(TAG,
"Results from i2c bus scan:");
70 ESP_LOGI(TAG,
"Found no i2c devices!");
74 ESP_LOGI(TAG,
"Found i2c device at address 0x%02X", s.first);
76 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
87 ESP_LOGVV(TAG,
"i2c bus not initialized!");
90 size_t to_request = 0;
91 for (
size_t i = 0; i < cnt; i++)
92 to_request += buffers[i].
len;
93 size_t ret =
wire_->requestFrom((
int) address, (
int) to_request, 1);
94 if (ret != to_request) {
95 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", to_request, address, ret);
99 for (
size_t i = 0; i < cnt; i++) {
100 const auto &buf = buffers[i];
101 for (
size_t j = 0; j < buf.len; j++)
105 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 107 std::string debug_hex;
109 for (
size_t i = 0; i < cnt; i++) {
110 const auto &buf = buffers[i];
111 for (
size_t j = 0; j < buf.len; j++) {
112 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
113 debug_hex += debug_buf;
116 ESP_LOGVV(TAG,
"0x%02X RX %s", address, debug_hex.c_str());
125 ESP_LOGVV(TAG,
"i2c bus not initialized!");
129 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 131 std::string debug_hex;
133 for (
size_t i = 0; i < cnt; i++) {
134 const auto &buf = buffers[i];
135 for (
size_t j = 0; j < buf.len; j++) {
136 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
137 debug_hex += debug_buf;
140 ESP_LOGVV(TAG,
"0x%02X TX %s", address, debug_hex.c_str());
143 wire_->beginTransmission(address);
145 for (
size_t i = 0; i < cnt; i++) {
146 const auto &buf = buffers[i];
149 size_t ret =
wire_->write(buf.data, buf.len);
151 if (ret != buf.len) {
152 ESP_LOGVV(TAG,
"TX failed at %u", written);
159 }
else if (status == 1) {
161 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
163 }
else if (status == 2 || status == 3) {
164 ESP_LOGVV(TAG,
"TX failed: not acknowledged");
167 ESP_LOGVV(TAG,
"TX failed: unknown error %u", status);
174 void ArduinoI2CBus::recover_() {
175 ESP_LOGI(TAG,
"Performing I2C bus recovery");
181 const auto half_period_usec = 1000000 / 100000 / 2;
191 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the I2C bus");
209 for (
auto i = 0; i < 9; i++) {
225 while (wait-- && digitalRead(
scl_pin_) == LOW) {
229 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
244 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
279 #endif // USE_ESP_IDF
std::vector< std::pair< uint8_t, bool > > scan_results_
void dump_config() override
ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t cnt, bool stop) override
ErrorCode readv(uint8_t address, ReadBuffer *buffers, size_t cnt) override
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
void IRAM_ATTR HOT delay(uint32_t ms)