1#if defined(USE_ARDUINO) && !defined(USE_ESP32)
12static const char *
const TAG =
"i2c.arduino";
15static constexpr size_t I2C_MAX_LOG_BYTES = 32;
20#if defined(USE_ESP8266)
21 wire_ =
new TwoWire();
22#elif defined(USE_RP2040)
23 static bool first =
true;
32 this->set_pins_and_clock_();
36 ESP_LOGV(TAG,
"Scanning bus for active devices");
41void ArduinoI2CBus::set_pins_and_clock_() {
50#if defined(USE_ESP8266)
53#elif defined(USE_RP2040)
62 ESP_LOGCONFIG(TAG,
"I2C Bus:");
69#if defined(USE_ESP8266)
70 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
71#elif defined(USE_RP2040)
72 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
75 switch (this->recovery_result_) {
77 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
80 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
83 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
87 ESP_LOGI(TAG,
"Results from bus scan:");
89 ESP_LOGI(TAG,
"Found no devices");
93 ESP_LOGI(TAG,
"Found device at address 0x%02X", s.first);
95 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
103 uint8_t *read_buffer,
size_t read_count) {
104#if defined(USE_ESP8266)
105 this->set_pins_and_clock_();
108 ESP_LOGD(TAG,
"i2c bus not initialized!");
112#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
118 if (write_count != 0 || read_count == 0) {
120 size_t ret =
wire_->write(write_buffer, write_count);
121 if (ret != write_count) {
122 ESP_LOGV(TAG,
"TX failed");
127 if (
status == 0 && read_count != 0) {
128 size_t ret2 =
wire_->requestFrom(
address, read_count,
true);
129 if (ret2 != read_count) {
130 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", read_count,
address, ret2);
133 for (
size_t j = 0; j != read_count; j++)
134 read_buffer[j] =
wire_->read();
140 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
144 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %u",
status);
148 ESP_LOGVV(TAG,
"TX failed: timeout");
151 ESP_LOGVV(TAG,
"TX failed: unknown error %u",
status);
158void ArduinoI2CBus::recover_() {
159 ESP_LOGI(TAG,
"Performing bus recovery");
165 const auto half_period_usec = 1000000 / 100000 / 2;
175 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the bus");
193 for (
auto i = 0; i < 9; i++) {
212 while (wait-- && digitalRead(
scl_pin_) == LOW) {
217 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
232 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
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
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.