12 static const char *
const TAG =
"i2c.arduino";
18 static uint8_t next_bus_num = 0;
19 if (next_bus_num == 0) {
22 wire_ =
new TwoWire(next_bus_num);
33 ESP_LOGV(TAG,
"Scanning i2c bus for active devices...");
38 ESP_LOGCONFIG(TAG,
"I2C Bus:");
39 ESP_LOGCONFIG(TAG,
" SDA Pin: GPIO%u", this->
sda_pin_);
40 ESP_LOGCONFIG(TAG,
" SCL Pin: GPIO%u", this->
scl_pin_);
41 ESP_LOGCONFIG(TAG,
" Frequency: %u Hz", this->
frequency_);
42 switch (this->recovery_result_) {
44 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
47 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
50 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
54 ESP_LOGI(TAG,
"Results from i2c bus scan:");
56 ESP_LOGI(TAG,
"Found no i2c devices!");
60 ESP_LOGI(TAG,
"Found i2c device at address 0x%02X", s.first);
62 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
73 ESP_LOGVV(TAG,
"i2c bus not initialized!");
76 size_t to_request = 0;
77 for (
size_t i = 0; i < cnt; i++)
78 to_request += buffers[i].
len;
79 size_t ret =
wire_->requestFrom((
int) address, (
int) to_request, 1);
80 if (ret != to_request) {
81 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", to_request, address, ret);
85 for (
size_t i = 0; i < cnt; i++) {
86 const auto &buf = buffers[i];
87 for (
size_t j = 0; j < buf.len; j++)
91 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 93 std::string debug_hex;
95 for (
size_t i = 0; i < cnt; i++) {
96 const auto &buf = buffers[i];
97 for (
size_t j = 0; j < buf.len; j++) {
98 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
99 debug_hex += debug_buf;
102 ESP_LOGVV(TAG,
"0x%02X RX %s", address, debug_hex.c_str());
111 ESP_LOGVV(TAG,
"i2c bus not initialized!");
115 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 117 std::string debug_hex;
119 for (
size_t i = 0; i < cnt; i++) {
120 const auto &buf = buffers[i];
121 for (
size_t j = 0; j < buf.len; j++) {
122 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
123 debug_hex += debug_buf;
126 ESP_LOGVV(TAG,
"0x%02X TX %s", address, debug_hex.c_str());
129 wire_->beginTransmission(address);
131 for (
size_t i = 0; i < cnt; i++) {
132 const auto &buf = buffers[i];
135 size_t ret =
wire_->write(buf.data, buf.len);
137 if (ret != buf.len) {
138 ESP_LOGVV(TAG,
"TX failed at %u", written);
142 uint8_t status =
wire_->endTransmission(stop);
145 }
else if (status == 1) {
147 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
149 }
else if (status == 2 || status == 3) {
150 ESP_LOGVV(TAG,
"TX failed: not acknowledged");
153 ESP_LOGVV(TAG,
"TX failed: unknown error %u", status);
160 void ArduinoI2CBus::recover_() {
161 ESP_LOGI(TAG,
"Performing I2C bus recovery");
167 const auto half_period_usec = 1000000 / 100000 / 2;
177 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the I2C bus");
195 for (
auto i = 0; i < 9; i++) {
211 while (wait-- && digitalRead(
scl_pin_) == LOW) {
215 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
230 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
265 #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)