1#if defined(USE_ARDUINO) && !defined(USE_ESP32) && !defined(USE_LIBRETINY)
15static constexpr size_t I2C_MAX_LOG_BYTES = 32;
20#if defined(USE_ESP8266)
21 wire_ =
new TwoWire();
34 this->set_pins_and_clock_();
38 ESP_LOGV(TAG,
"Scanning bus for active devices");
43void ArduinoI2CBus::set_pins_and_clock_() {
52#if defined(USE_ESP8266)
64 ESP_LOGCONFIG(TAG,
"I2C Bus:");
71#if defined(USE_ESP8266)
72 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
74 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
77 switch (this->recovery_result_) {
79 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
82 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
85 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
89 ESP_LOGI(TAG,
"Results from bus scan:");
91 ESP_LOGI(TAG,
"Found no devices");
95 ESP_LOGI(TAG,
"Found device at address 0x%02X", s.first);
97 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
105 uint8_t *read_buffer,
size_t read_count) {
106#if defined(USE_ESP8266)
107 this->set_pins_and_clock_();
110 ESP_LOGD(TAG,
"i2c bus not initialized!");
114 ESP_LOGV_HEX(TAG, write_buffer, write_count, I2C_MAX_LOG_BYTES,
"0x%02X TX %s",
address);
117 if (write_count != 0 || read_count == 0) {
118 this->
wire_->beginTransmission(address);
119 size_t ret = this->
wire_->write(write_buffer, write_count);
120 if (
ret != write_count) {
121 ESP_LOGV(TAG,
"TX failed");
124 status = this->
wire_->endTransmission(read_count == 0);
126 if (
status == 0 && read_count != 0) {
127 size_t ret2 = this->
wire_->requestFrom(address, read_count,
true);
128 if (ret2 != read_count) {
129 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", read_count,
address, ret2);
132 for (
size_t j = 0; j != read_count; j++)
133 read_buffer[j] = this->
wire_->read();
139 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
143 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %u",
status);
147 ESP_LOGVV(TAG,
"TX failed: timeout");
150 ESP_LOGVV(TAG,
"TX failed: unknown error %u",
status);
154#ifdef I2C_PORT_FREQUENCY_COUNT
170void ArduinoI2CBus::recover_() {
171 ESP_LOGI(TAG,
"Performing bus recovery");
177 const auto half_period_usec = 1000000 / 100000 / 2;
180 pinMode(this->
scl_pin_, INPUT_PULLUP);
186 if (digitalRead(this->
scl_pin_) == LOW) {
187 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the bus");
205 for (
auto i = 0; i < 9; i++) {
213 pinMode(this->
scl_pin_, INPUT_PULLUP);
224 while (wait-- && digitalRead(this->
scl_pin_) == LOW) {
228 if (digitalRead(this->
scl_pin_) == LOW) {
229 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
237 pinMode(this->
sda_pin_, INPUT_PULLUP);
243 if (digitalRead(this->
sda_pin_) == LOW) {
244 ESP_LOGE(TAG,
"Recovery failed: SDA is held LOW after clock pulse cycle");
272 pinMode(this->
sda_pin_, INPUT_PULLUP);
void feed_wdt()
Feed the task watchdog.
void dump_config() override
ErrorCode switch_frequency(uint32_t frequency) 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
ESPHOME_LOG_TAG(TAG, "i2c")
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Application App
Global storage of Application pointer - only one Application can exist.