1#if defined(USE_ARDUINO) && !defined(USE_ESP32)
13static const char *
const TAG =
"i2c.arduino";
16static constexpr size_t I2C_MAX_LOG_BYTES = 32;
21#if defined(USE_ESP8266)
22 wire_ =
new TwoWire();
23#elif defined(USE_RP2040)
24 static bool first =
true;
33 this->set_pins_and_clock_();
37 ESP_LOGV(TAG,
"Scanning bus for active devices");
42void ArduinoI2CBus::set_pins_and_clock_() {
51#if defined(USE_ESP8266)
54#elif defined(USE_RP2040)
63 ESP_LOGCONFIG(TAG,
"I2C Bus:");
70#if defined(USE_ESP8266)
71 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
72#elif defined(USE_RP2040)
73 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
76 switch (this->recovery_result_) {
78 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
81 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
84 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
88 ESP_LOGI(TAG,
"Results from bus scan:");
90 ESP_LOGI(TAG,
"Found no devices");
94 ESP_LOGI(TAG,
"Found device at address 0x%02X", s.first);
96 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
104 uint8_t *read_buffer,
size_t read_count) {
105#if defined(USE_ESP8266)
106 this->set_pins_and_clock_();
109 ESP_LOGD(TAG,
"i2c bus not initialized!");
113#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
119 if (write_count != 0 || read_count == 0) {
121 size_t ret =
wire_->write(write_buffer, write_count);
122 if (ret != write_count) {
123 ESP_LOGV(TAG,
"TX failed");
128 if (
status == 0 && read_count != 0) {
129 size_t ret2 =
wire_->requestFrom(
address, read_count,
true);
130 if (ret2 != read_count) {
131 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", read_count,
address, ret2);
134 for (
size_t j = 0; j != read_count; j++)
135 read_buffer[j] =
wire_->read();
142 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
146 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %d",
status);
149 ESP_LOGVV(TAG,
"TX failed: timeout");
153 ESP_LOGVV(TAG,
"TX failed: unknown error %u",
status);
161void ArduinoI2CBus::recover_() {
162 ESP_LOGI(TAG,
"Performing bus recovery");
168 const auto half_period_usec = 1000000 / 100000 / 2;
178 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the bus");
196 for (
auto i = 0; i < 9; i++) {
215 while (wait-- && digitalRead(
scl_pin_) == LOW) {
220 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
235 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 write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count, uint8_t *read_buffer, size_t read_count) 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
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
@ 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)
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
constexpr size_t format_hex_pretty_size(size_t byte_count)
Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0".
Application App
Global storage of Application pointer - only one Application can exist.