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) 27 wire_ =
new TwoWire();
28 #elif defined(USE_RP2040) 29 static bool first =
true;
38 this->set_pins_and_clock_();
42 ESP_LOGV(TAG,
"Scanning i2c bus for active devices...");
47 void ArduinoI2CBus::set_pins_and_clock_() {
56 #if defined(USE_ESP32) 59 #elif defined(USE_ESP8266) 62 #elif defined(USE_RP2040) 71 ESP_LOGCONFIG(TAG,
"I2C Bus:");
72 ESP_LOGCONFIG(TAG,
" SDA Pin: GPIO%u", this->
sda_pin_);
73 ESP_LOGCONFIG(TAG,
" SCL Pin: GPIO%u", this->
scl_pin_);
74 ESP_LOGCONFIG(TAG,
" Frequency: %u Hz", this->
frequency_);
76 #if defined(USE_ESP32) 77 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
78 #elif defined(USE_ESP8266) 79 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
80 #elif defined(USE_RP2040) 81 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
84 switch (this->recovery_result_) {
86 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
89 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
92 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
96 ESP_LOGI(TAG,
"Results from i2c bus scan:");
98 ESP_LOGI(TAG,
"Found no i2c devices!");
102 ESP_LOGI(TAG,
"Found i2c device at address 0x%02X", s.first);
104 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
112 #if defined(USE_ESP8266) 113 this->set_pins_and_clock_();
119 ESP_LOGVV(TAG,
"i2c bus not initialized!");
122 size_t to_request = 0;
123 for (
size_t i = 0; i < cnt; i++)
124 to_request += buffers[i].
len;
125 size_t ret =
wire_->requestFrom((
int) address, (
int) to_request, 1);
126 if (ret != to_request) {
127 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", to_request, address, ret);
131 for (
size_t i = 0; i < cnt; i++) {
132 const auto &buf = buffers[i];
133 for (
size_t j = 0; j < buf.len; j++)
137 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 139 std::string debug_hex;
141 for (
size_t i = 0; i < cnt; i++) {
142 const auto &buf = buffers[i];
143 for (
size_t j = 0; j < buf.len; j++) {
144 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
145 debug_hex += debug_buf;
148 ESP_LOGVV(TAG,
"0x%02X RX %s", address, debug_hex.c_str());
154 #if defined(USE_ESP8266) 155 this->set_pins_and_clock_();
161 ESP_LOGVV(TAG,
"i2c bus not initialized!");
165 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE 167 std::string debug_hex;
169 for (
size_t i = 0; i < cnt; i++) {
170 const auto &buf = buffers[i];
171 for (
size_t j = 0; j < buf.len; j++) {
172 snprintf(debug_buf,
sizeof(debug_buf),
"%02X", buf.data[j]);
173 debug_hex += debug_buf;
176 ESP_LOGVV(TAG,
"0x%02X TX %s", address, debug_hex.c_str());
179 wire_->beginTransmission(address);
181 for (
size_t i = 0; i < cnt; i++) {
182 const auto &buf = buffers[i];
185 size_t ret =
wire_->write(buf.data, buf.len);
187 if (ret != buf.len) {
188 ESP_LOGVV(TAG,
"TX failed at %u", written);
198 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
202 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %d", status);
205 ESP_LOGVV(TAG,
"TX failed: timeout");
209 ESP_LOGVV(TAG,
"TX failed: unknown error %u", status);
217 void ArduinoI2CBus::recover_() {
218 ESP_LOGI(TAG,
"Performing I2C bus recovery");
224 const auto half_period_usec = 1000000 / 100000 / 2;
234 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the I2C bus");
252 for (
auto i = 0; i < 9; i++) {
271 while (wait-- && digitalRead(
scl_pin_) == LOW) {
276 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
291 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
326 #endif // USE_ESP_IDF the WriteBuffer structure stores a pointer to a write buffer and its length
void i2c_scan_()
Scans the I2C bus for devices.
std::vector< std::pair< uint8_t, bool > > scan_results_
array containing scan results
the ReadBuffer structure stores a pointer to a read buffer and its length
void dump_config() override
uint8_t * data
pointer to the read buffer
timeout while waiting to receive bytes
No error found during execution of method.
I2C bus acknowledgment not received.
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
bool scan_
Should we scan ? Can be set in the yaml.
ErrorCode readv(uint8_t address, ReadBuffer *buffers, size_t cnt) override
Implementation of SPI Controller mode.
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
miscellaneous I2C error during execution
call method to a not initialized bus