1#if defined(USE_ARDUINO) && !defined(USE_ESP32)
13static const char *
const TAG =
"i2c.arduino";
18#if defined(USE_ESP8266)
19 wire_ =
new TwoWire();
20#elif defined(USE_RP2040)
21 static bool first =
true;
30 this->set_pins_and_clock_();
34 ESP_LOGV(TAG,
"Scanning bus for active devices");
39void ArduinoI2CBus::set_pins_and_clock_() {
48#if defined(USE_ESP8266)
51#elif defined(USE_RP2040)
60 ESP_LOGCONFIG(TAG,
"I2C Bus:");
67#if defined(USE_ESP8266)
68 ESP_LOGCONFIG(TAG,
" Timeout: %u us", this->
timeout_);
69#elif defined(USE_RP2040)
70 ESP_LOGCONFIG(TAG,
" Timeout: %u ms", this->
timeout_ / 1000);
73 switch (this->recovery_result_) {
75 ESP_LOGCONFIG(TAG,
" Recovery: bus successfully recovered");
78 ESP_LOGCONFIG(TAG,
" Recovery: failed, SCL is held low on the bus");
81 ESP_LOGCONFIG(TAG,
" Recovery: failed, SDA is held low on the bus");
85 ESP_LOGI(TAG,
"Results from bus scan:");
87 ESP_LOGI(TAG,
"Found no devices");
91 ESP_LOGI(TAG,
"Found device at address 0x%02X", s.first);
93 ESP_LOGE(TAG,
"Unknown error at address 0x%02X", s.first);
101 uint8_t *read_buffer,
size_t read_count) {
102#if defined(USE_ESP8266)
103 this->set_pins_and_clock_();
106 ESP_LOGD(TAG,
"i2c bus not initialized!");
113 if (write_count != 0 || read_count == 0) {
115 size_t ret =
wire_->write(write_buffer, write_count);
116 if (ret != write_count) {
117 ESP_LOGV(TAG,
"TX failed");
122 if (
status == 0 && read_count != 0) {
123 size_t ret2 =
wire_->requestFrom(
address, read_count,
true);
124 if (ret2 != read_count) {
125 ESP_LOGVV(TAG,
"RX %u from %02X failed with error %u", read_count,
address, ret2);
128 for (
size_t j = 0; j != read_count; j++)
129 read_buffer[j] =
wire_->read();
136 ESP_LOGVV(TAG,
"TX failed: buffer not large enough");
140 ESP_LOGVV(TAG,
"TX failed: not acknowledged: %d",
status);
143 ESP_LOGVV(TAG,
"TX failed: timeout");
147 ESP_LOGVV(TAG,
"TX failed: unknown error %u",
status);
155void ArduinoI2CBus::recover_() {
156 ESP_LOGI(TAG,
"Performing bus recovery");
162 const auto half_period_usec = 1000000 / 100000 / 2;
172 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW on the bus");
190 for (
auto i = 0; i < 9; i++) {
209 while (wait-- && digitalRead(
scl_pin_) == LOW) {
214 ESP_LOGE(TAG,
"Recovery failed: SCL is held LOW during clock pulse cycle");
229 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)
std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length)
Format a byte array in pretty-printed, human-readable hex format.
Application App
Global storage of Application pointer - only one Application can exist.