13static const char *
const TAG =
"i2c.arduino";
16 ESP_LOGCONFIG(TAG,
"Running setup");
20 static uint8_t next_bus_num = 0;
21 if (next_bus_num == 0) {
24 wire_ =
new TwoWire(next_bus_num);
27#elif defined(USE_ESP8266)
28 wire_ =
new TwoWire();
29#elif defined(USE_RP2040)
30 static bool first =
true;
39 this->set_pins_and_clock_();
43 ESP_LOGV(TAG,
"Scanning bus for active devices");
48void ArduinoI2CBus::set_pins_and_clock_() {
60#elif defined(USE_ESP8266)
63#elif defined(USE_RP2040)
72 ESP_LOGCONFIG(TAG,
"I2C Bus:");
80 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
81#elif defined(USE_ESP8266)
82 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
83#elif defined(USE_RP2040)
84 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
87 switch (this->recovery_result_) {
89 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
92 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
95 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
99 ESP_LOGI(TAG,
"Results from bus scan:");
101 ESP_LOGI(TAG,
"Found no devices");
105 ESP_LOGI(TAG,
"Found device at address 0x%02X", s.first);
107 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
115#if defined(USE_ESP8266)
116 this->set_pins_and_clock_();
122 ESP_LOGVV(TAG,
"i2c bus not initialized!");
125 size_t to_request = 0;
126 for (
size_t i = 0; i < cnt; i++)
127 to_request += buffers[i].
len;
128 size_t ret =
wire_->requestFrom((
int)
address, (
int) to_request, 1);
129 if (ret != to_request) {
130 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", to_request,
address, ret);
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++)
140#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
142 std::string debug_hex;
144 for (
size_t i = 0; i < cnt; i++) {
145 const auto &buf = buffers[i];
146 for (
size_t j = 0; j < buf.len; j++) {
147 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
148 debug_hex += debug_buf;
151 ESP_LOGVV(TAG,
"0x%02X RX %s",
address, debug_hex.c_str());
157#if defined(USE_ESP8266)
158 this->set_pins_and_clock_();
164 ESP_LOGVV(TAG,
"i2c bus not initialized!");
168#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
170 std::string debug_hex;
172 for (
size_t i = 0; i < cnt; i++) {
173 const auto &buf = buffers[i];
174 for (
size_t j = 0; j < buf.len; j++) {
175 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
176 debug_hex += debug_buf;
179 ESP_LOGVV(TAG,
"0x%02X TX %s",
address, debug_hex.c_str());
184 for (
size_t i = 0; i < cnt; i++) {
185 const auto &buf = buffers[i];
188 size_t ret =
wire_->write(buf.data, buf.len);
190 if (ret != buf.len) {
191 ESP_LOGVV(TAG,
"TX failed at %u", written);
201 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
205 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %d",
status);
208 ESP_LOGVV(TAG,
"TX failed: timeout");
212 ESP_LOGVV(TAG,
"TX failed: unknown error %u",
status);
220void ArduinoI2CBus::recover_() {
221 ESP_LOGI(TAG,
"Performing bus recovery");
227 const auto half_period_usec = 1000000 / 100000 / 2;
237 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the bus");
255 for (
auto i = 0; i < 9; i++) {
274 while (wait-- && digitalRead(
scl_pin_) == LOW) {
279 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
294 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
void feed_wdt(uint32_t time=0)
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
bool scan_
Should we scan ? Can be set in the yaml.
std::vector< std::pair< uint8_t, bool > > scan_results_
array containing scan results
void i2c_scan_()
Scans the I2C bus for devices.
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
@ ERROR_OK
No error found during execution of method.
@ ERROR_TIMEOUT
timeout while waiting to receive bytes
@ ERROR_NOT_ACKNOWLEDGED
I2C bus acknowledgment not received.
@ ERROR_NOT_INITIALIZED
call method to a not initialized bus
@ ERROR_UNKNOWN
miscellaneous I2C error during execution
@ RECOVERY_FAILED_SDA_LOW
@ RECOVERY_FAILED_SCL_LOW
Providing packet encoding functions for exchanging data with a remote host.
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Application App
Global storage of Application pointer - only one Application can exist.
the ReadBuffer structure stores a pointer to a read buffer and its length
uint8_t * data
pointer to the read buffer
the WriteBuffer structure stores a pointer to a write buffer and its length