ESPHome 2025.12.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
12 if (!device_is_ready(this->i2c_dev_)) {
13 ESP_LOGE(TAG, "I2C dev is not ready.");
15 return;
16 }
17
18 int ret = i2c_configure(this->i2c_dev_, this->dev_config_);
19 if (ret < 0) {
20 ESP_LOGE(TAG, "I2C: Failed to configure device");
21 }
22
23 this->recovery_result_ = i2c_recover_bus(this->i2c_dev_);
24 if (this->recovery_result_ != 0) {
25 ESP_LOGE(TAG, "I2C recover bus failed, err %d", this->recovery_result_);
26 }
27 if (this->scan_) {
28 ESP_LOGV(TAG, "Scanning I2C bus for active devices...");
29 this->i2c_scan_();
30 }
31}
32
34 auto get_speed = [](uint32_t dev_config) {
35 switch (I2C_SPEED_GET(dev_config)) {
36 case I2C_SPEED_STANDARD:
37 return "100 kHz";
38 case I2C_SPEED_FAST:
39 return "400 kHz";
40 case I2C_SPEED_FAST_PLUS:
41 return "1 MHz";
42 case I2C_SPEED_HIGH:
43 return "3.4 MHz";
44 case I2C_SPEED_ULTRA:
45 return "5 MHz";
46 }
47 return "unknown";
48 };
49 ESP_LOGCONFIG(TAG,
50 "I2C Bus:\n"
51 " SDA Pin: GPIO%u\n"
52 " SCL Pin: GPIO%u\n"
53 " Frequency: %s\n"
54 " Name: %s",
55 this->sda_pin_, this->scl_pin_, get_speed(this->dev_config_), this->i2c_dev_->name);
56
57 if (this->recovery_result_ != 0) {
58 ESP_LOGCONFIG(TAG, " Recovery: failed, err %d", this->recovery_result_);
59 } else {
60 ESP_LOGCONFIG(TAG, " Recovery: bus successfully recovered");
61 }
62 if (this->scan_) {
63 ESP_LOGI(TAG, "Results from I2C bus scan:");
64 if (scan_results_.empty()) {
65 ESP_LOGI(TAG, "Found no I2C devices!");
66 } else {
67 for (const auto &s : scan_results_) {
68 if (s.second) {
69 ESP_LOGI(TAG, "Found I2C device at address 0x%02X", s.first);
70 } else {
71 ESP_LOGE(TAG, "Unknown error at address 0x%02X", s.first);
72 }
73 }
74 }
75 }
76}
77
78ErrorCode ZephyrI2CBus::write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count,
79 uint8_t *read_buffer, size_t read_count) {
80 if (!device_is_ready(this->i2c_dev_)) {
82 }
83
84 i2c_msg msgs[2]{};
85 size_t cnt = 0;
86 uint8_t dst = 0x00; // dummy data to not use random value
87
88 if (read_count == 0 && write_count == 0) {
89 msgs[cnt].buf = &dst;
90 msgs[cnt].len = 0U;
91 msgs[cnt++].flags = I2C_MSG_WRITE;
92 } else {
93 if (write_count) {
94 // the same struct is used for read/write — const cast is fine; data isn't modified
95 msgs[cnt].buf = const_cast<uint8_t *>(write_buffer);
96 msgs[cnt].len = write_count;
97 msgs[cnt++].flags = I2C_MSG_WRITE;
98 }
99 if (read_count) {
100 msgs[cnt].buf = const_cast<uint8_t *>(read_buffer);
101 msgs[cnt].len = read_count;
102 msgs[cnt++].flags = I2C_MSG_READ | I2C_MSG_RESTART;
103 }
104 }
105
106 msgs[cnt - 1].flags |= I2C_MSG_STOP;
107
108 auto err = i2c_transfer(this->i2c_dev_, msgs, cnt, address);
109
110 if (err == -EIO) {
112 }
113
114 if (err != 0) {
115 ESP_LOGE(TAG, "i2c transfer error %d", err);
116 return ERROR_UNKNOWN;
117 }
118
119 return ERROR_OK;
120}
121
123 this->dev_config_ &= ~I2C_SPEED_MASK;
124 if (frequency >= 400000) {
125 this->dev_config_ |= I2C_SPEED_SET(I2C_SPEED_FAST);
126 } else {
127 this->dev_config_ |= I2C_SPEED_SET(I2C_SPEED_STANDARD);
128 }
129}
130
131} // namespace esphome::i2c
132
133#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