ESPHome 2025.11.0
Loading...
Searching...
No Matches
i2c.cpp
Go to the documentation of this file.
1#include "i2c.h"
2
4#include "esphome/core/hal.h"
5#include "esphome/core/log.h"
6#include <memory>
7
8namespace esphome {
9namespace i2c {
10
11static const char *const TAG = "i2c";
12
13void I2CBus::i2c_scan_() {
14 // suppress logs from the IDF I2C library during the scan
15#if defined(USE_ESP32) && defined(USE_LOGGER)
16 auto previous = esp_log_level_get("*");
17 esp_log_level_set("*", ESP_LOG_NONE);
18#endif
19
20 for (uint8_t address = 8; address != 120; address++) {
21 auto err = write_readv(address, nullptr, 0, nullptr, 0);
22 if (err == ERROR_OK) {
23 scan_results_.emplace_back(address, true);
24 } else if (err == ERROR_UNKNOWN) {
25 scan_results_.emplace_back(address, false);
26 }
27 // it takes 16sec to scan on nrf52. It prevents board reset.
29 }
30#if defined(USE_ESP32) && defined(USE_LOGGER)
31 esp_log_level_set("*", previous);
32#endif
33}
34
35ErrorCode I2CDevice::read_register(uint8_t a_register, uint8_t *data, size_t len) {
36 return bus_->write_readv(this->address_, &a_register, 1, data, len);
37}
38
39ErrorCode I2CDevice::read_register16(uint16_t a_register, uint8_t *data, size_t len) {
40 a_register = convert_big_endian(a_register);
41 return bus_->write_readv(this->address_, reinterpret_cast<const uint8_t *>(&a_register), 2, data, len);
42}
43
44ErrorCode I2CDevice::write_register(uint8_t a_register, const uint8_t *data, size_t len) const {
45 SmallBufferWithHeapFallback<17> buffer_alloc; // Most I2C writes are <= 16 bytes
46 uint8_t *buffer = buffer_alloc.get(len + 1);
47
48 buffer[0] = a_register;
49 std::copy(data, data + len, buffer + 1);
50 return this->bus_->write_readv(this->address_, buffer, len + 1, nullptr, 0);
51}
52
53ErrorCode I2CDevice::write_register16(uint16_t a_register, const uint8_t *data, size_t len) const {
54 SmallBufferWithHeapFallback<18> buffer_alloc; // Most I2C writes are <= 16 bytes + 2 for register
55 uint8_t *buffer = buffer_alloc.get(len + 2);
56
57 buffer[0] = a_register >> 8;
58 buffer[1] = a_register;
59 std::copy(data, data + len, buffer + 2);
60 return this->bus_->write_readv(this->address_, buffer, len + 2, nullptr, 0);
61}
62
63bool I2CDevice::read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len) {
64 if (read_register(a_register, reinterpret_cast<uint8_t *>(data), len * 2) != ERROR_OK)
65 return false;
66 for (size_t i = 0; i < len; i++)
67 data[i] = i2ctohs(data[i]);
68 return true;
69}
70
71bool I2CDevice::write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const {
72 // we have to copy in order to be able to change byte order
73 std::unique_ptr<uint16_t[]> temp{new uint16_t[len]};
74 for (size_t i = 0; i < len; i++)
75 temp[i] = htoi2cs(data[i]);
76 return write_register(a_register, reinterpret_cast<const uint8_t *>(temp.get()), len * 2) == ERROR_OK;
77}
78
80 this->parent_->write_register(this->register_, &value, 1);
81 return *this;
82}
84 value &= get();
85 this->parent_->write_register(this->register_, &value, 1);
86 return *this;
87}
89 value |= get();
90 this->parent_->write_register(this->register_, &value, 1);
91 return *this;
92}
93
94uint8_t I2CRegister::get() const {
95 uint8_t value = 0x00;
96 this->parent_->read_register(this->register_, &value, 1);
97 return value;
98}
99
101 this->parent_->write_register16(this->register_, &value, 1);
102 return *this;
103}
105 value &= get();
106 this->parent_->write_register16(this->register_, &value, 1);
107 return *this;
108}
110 value |= get();
111 this->parent_->write_register16(this->register_, &value, 1);
112 return *this;
113}
114
115uint8_t I2CRegister16::get() const {
116 uint8_t value = 0x00;
117 this->parent_->read_register16(this->register_, &value, 1);
118 return value;
119}
120
121} // namespace i2c
122} // namespace esphome
uint8_t address
Definition bl0906.h:4
virtual ErrorCode write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count, uint8_t *read_buffer, size_t read_count)=0
This virtual method writes bytes to an I2CBus from an array, then reads bytes into an array of ReadBu...
std::vector< std::pair< uint8_t, bool > > scan_results_
array containing scan results
Definition i2c_bus.h:135
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len) const
writes an array of bytes to a specific register in the I²C device
Definition i2c.cpp:44
ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len) const
write an array of bytes to a specific register in the I²C device
Definition i2c.cpp:53
bool write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const
Definition i2c.cpp:71
I2CBus * bus_
pointer to I2CBus instance
Definition i2c.h:303
uint8_t address_
store the address of the device on the bus
Definition i2c.h:302
ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:39
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:35
bool read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len)
Definition i2c.cpp:63
uint8_t size_t len
Definition i2c.h:273
This class is used to create I2CRegister16 objects that act as proxies to read/write internal registe...
Definition i2c.h:88
uint16_t register_
the internal 16 bits address of the register
Definition i2c.h:123
I2CRegister16 & operator&=(uint8_t value)
overloads the compound &= operator.
Definition i2c.cpp:104
I2CRegister16 & operator|=(uint8_t value)
overloads the compound |= operator.
Definition i2c.cpp:109
I2CDevice * parent_
I2CDevice object pointer.
Definition i2c.h:122
uint8_t get() const
returns the register value
Definition i2c.cpp:115
I2CRegister16 & operator=(uint8_t value)
overloads the = operator.
Definition i2c.cpp:100
This class is used to create I2CRegister objects that act as proxies to read/write internal registers...
Definition i2c.h:33
I2CRegister & operator|=(uint8_t value)
overloads the compound |= operator.
Definition i2c.cpp:88
uint8_t get() const
returns the register value
Definition i2c.cpp:94
I2CRegister & operator&=(uint8_t value)
overloads the compound &= operator.
Definition i2c.cpp:83
I2CDevice * parent_
I2CDevice object pointer.
Definition i2c.h:67
uint8_t register_
the internal address of the register
Definition i2c.h:68
I2CRegister & operator=(uint8_t value)
overloads the = operator.
Definition i2c.cpp:79
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large.
Definition i2c_bus.h:15
uint16_t i2ctohs(uint16_t i2cshort)
Definition i2c.h:128
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition i2c_bus.h:31
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:33
@ ERROR_UNKNOWN
miscellaneous I2C error during execution
Definition i2c_bus.h:39
uint16_t htoi2cs(uint16_t hostshort)
Definition i2c.h:129
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
Definition helpers.h:433
std::string size_t len
Definition helpers.h:483
void IRAM_ATTR HOT arch_feed_wdt()
Definition core.cpp:68