ESPHome 2026.1.0-dev
Loading...
Searching...
No Matches
i2c_bus_zephyr.cpp
Go to the documentation of this file.
1#ifdef USE_ZEPHYR
2
3#include "i2c_bus_zephyr.h"
4#include <zephyr/drivers/i2c.h>
5#include "esphome/core/log.h"
6
7namespace esphome::i2c {
8
9static const char *const TAG = "i2c.zephyr";
10
11static const char *get_speed(uint32_t dev_config) {
12 switch (I2C_SPEED_GET(dev_config)) {
13 case I2C_SPEED_STANDARD:
14 return "100 kHz";
15 case I2C_SPEED_FAST:
16 return "400 kHz";
17 case I2C_SPEED_FAST_PLUS:
18 return "1 MHz";
19 case I2C_SPEED_HIGH:
20 return "3.4 MHz";
21 case I2C_SPEED_ULTRA:
22 return "5 MHz";
23 }
24 return "unknown";
25}
26
28 if (!device_is_ready(this->i2c_dev_)) {
29 ESP_LOGE(TAG, "I2C dev is not ready.");
31 return;
32 }
33
34 int ret = i2c_configure(this->i2c_dev_, this->dev_config_);
35 if (ret < 0) {
36 ESP_LOGE(TAG, "I2C: Failed to configure device");
37 }
38
39 this->recovery_result_ = i2c_recover_bus(this->i2c_dev_);
40 if (this->recovery_result_ != 0) {
41 ESP_LOGE(TAG, "I2C recover bus failed, err %d", this->recovery_result_);
42 }
43 if (this->scan_) {
44 ESP_LOGV(TAG, "Scanning I2C bus for active devices...");
45 this->i2c_scan_();
46 }
47}
48
50 ESP_LOGCONFIG(TAG,
51 "I2C Bus:\n"
52 " SDA Pin: GPIO%u\n"
53 " SCL Pin: GPIO%u\n"
54 " Frequency: %s\n"
55 " Name: %s",
56 this->sda_pin_, this->scl_pin_, get_speed(this->dev_config_), this->i2c_dev_->name);
57
58 if (this->recovery_result_ != 0) {
59 ESP_LOGCONFIG(TAG, " Recovery: failed, err %d", this->recovery_result_);
60 } else {
61 ESP_LOGCONFIG(TAG, " Recovery: bus successfully recovered");
62 }
63 if (this->scan_) {
64 ESP_LOGI(TAG, "Results from I2C bus scan:");
65 if (scan_results_.empty()) {
66 ESP_LOGI(TAG, "Found no I2C devices!");
67 } else {
68 for (const auto &s : scan_results_) {
69 if (s.second) {
70 ESP_LOGI(TAG, "Found I2C device at address 0x%02X", s.first);
71 } else {
72 ESP_LOGE(TAG, "Unknown error at address 0x%02X", s.first);
73 }
74 }
75 }
76 }
77}
78
79ErrorCode ZephyrI2CBus::write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count,
80 uint8_t *read_buffer, size_t read_count) {
81 if (!device_is_ready(this->i2c_dev_)) {
83 }
84
85 i2c_msg msgs[2]{};
86 size_t cnt = 0;
87 uint8_t dst = 0x00; // dummy data to not use random value
88
89 if (read_count == 0 && write_count == 0) {
90 msgs[cnt].buf = &dst;
91 msgs[cnt].len = 0U;
92 msgs[cnt++].flags = I2C_MSG_WRITE;
93 } else {
94 if (write_count) {
95 // the same struct is used for read/write — const cast is fine; data isn't modified
96 msgs[cnt].buf = const_cast<uint8_t *>(write_buffer);
97 msgs[cnt].len = write_count;
98 msgs[cnt++].flags = I2C_MSG_WRITE;
99 }
100 if (read_count) {
101 msgs[cnt].buf = const_cast<uint8_t *>(read_buffer);
102 msgs[cnt].len = read_count;
103 msgs[cnt++].flags = I2C_MSG_READ | I2C_MSG_RESTART;
104 }
105 }
106
107 msgs[cnt - 1].flags |= I2C_MSG_STOP;
108
109 auto err = i2c_transfer(this->i2c_dev_, msgs, cnt, address);
110
111 if (err == -EIO) {
113 }
114
115 if (err != 0) {
116 ESP_LOGE(TAG, "i2c transfer error %d", err);
117 return ERROR_UNKNOWN;
118 }
119
120 return ERROR_OK;
121}
122
124 this->dev_config_ &= ~I2C_SPEED_MASK;
125 if (frequency >= 400000) {
126 this->dev_config_ |= I2C_SPEED_SET(I2C_SPEED_FAST);
127 } else {
128 this->dev_config_ |= I2C_SPEED_SET(I2C_SPEED_STANDARD);
129 }
130}
131
132} // namespace esphome::i2c
133
134#endif
uint8_t address
Definition bl0906.h:4
uint16_le_t frequency
Definition bl0942.h:6
virtual void mark_failed()
Mark this component as failed.
bool scan_
Should we scan ? Can be set in the yaml.
Definition i2c_bus.h:136
std::vector< std::pair< uint8_t, bool > > scan_results_
array containing scan results
Definition i2c_bus.h:135
void set_frequency(uint32_t frequency)
ErrorCode write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count, uint8_t *read_buffer, size_t read_count) override
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition i2c_bus.h:31
@ ERROR_NOT_ACKNOWLEDGED
I2C bus acknowledgment not received.
Definition i2c_bus.h:35
@ ERROR_NOT_INITIALIZED
call method to a not initialized bus
Definition i2c_bus.h:37
@ ERROR_UNKNOWN
miscellaneous I2C error during execution
Definition i2c_bus.h:39