ESPHome 2026.2.4
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 for (uint8_t address = 8; address != 120; address++) {
15 auto err = write_readv(address, nullptr, 0, nullptr, 0);
16 if (err == ERROR_OK) {
17 scan_results_.emplace_back(address, true);
18 } else if (err == ERROR_UNKNOWN) {
19 scan_results_.emplace_back(address, false);
20 }
21 // it takes 16sec to scan on nrf52. It prevents board reset.
23 }
24}
25
26ErrorCode I2CDevice::read_register(uint8_t a_register, uint8_t *data, size_t len) {
27 return bus_->write_readv(this->address_, &a_register, 1, data, len);
28}
29
30ErrorCode I2CDevice::read_register16(uint16_t a_register, uint8_t *data, size_t len) {
31 a_register = convert_big_endian(a_register);
32 return bus_->write_readv(this->address_, reinterpret_cast<const uint8_t *>(&a_register), 2, data, len);
33}
34
35ErrorCode I2CDevice::write_register(uint8_t a_register, const uint8_t *data, size_t len) const {
36 SmallBufferWithHeapFallback<17> buffer_alloc(len + 1); // Most I2C writes are <= 16 bytes
37 uint8_t *buffer = buffer_alloc.get();
38
39 buffer[0] = a_register;
40 std::copy(data, data + len, buffer + 1);
41 return this->bus_->write_readv(this->address_, buffer, len + 1, nullptr, 0);
42}
43
44ErrorCode I2CDevice::write_register16(uint16_t a_register, const uint8_t *data, size_t len) const {
45 SmallBufferWithHeapFallback<18> buffer_alloc(len + 2); // Most I2C writes are <= 16 bytes + 2 for register
46 uint8_t *buffer = buffer_alloc.get();
47
48 buffer[0] = a_register >> 8;
49 buffer[1] = a_register;
50 std::copy(data, data + len, buffer + 2);
51 return this->bus_->write_readv(this->address_, buffer, len + 2, nullptr, 0);
52}
53
54bool I2CDevice::read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len) {
55 if (read_register(a_register, reinterpret_cast<uint8_t *>(data), len * 2) != ERROR_OK)
56 return false;
57 for (size_t i = 0; i < len; i++)
58 data[i] = i2ctohs(data[i]);
59 return true;
60}
61
62bool I2CDevice::write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const {
63 // we have to copy in order to be able to change byte order
64 std::unique_ptr<uint16_t[]> temp{new uint16_t[len]};
65 for (size_t i = 0; i < len; i++)
66 temp[i] = htoi2cs(data[i]);
67 return write_register(a_register, reinterpret_cast<const uint8_t *>(temp.get()), len * 2) == ERROR_OK;
68}
69
71 this->parent_->write_register(this->register_, &value, 1);
72 return *this;
73}
75 value &= get();
76 this->parent_->write_register(this->register_, &value, 1);
77 return *this;
78}
80 value |= get();
81 this->parent_->write_register(this->register_, &value, 1);
82 return *this;
83}
84
85uint8_t I2CRegister::get() const {
86 uint8_t value = 0x00;
87 this->parent_->read_register(this->register_, &value, 1);
88 return value;
89}
90
92 this->parent_->write_register16(this->register_, &value, 1);
93 return *this;
94}
96 value &= get();
97 this->parent_->write_register16(this->register_, &value, 1);
98 return *this;
99}
101 value |= get();
102 this->parent_->write_register16(this->register_, &value, 1);
103 return *this;
104}
105
106uint8_t I2CRegister16::get() const {
107 uint8_t value = 0x00;
108 this->parent_->read_register16(this->register_, &value, 1);
109 return value;
110}
111
112} // namespace i2c
113} // namespace esphome
uint8_t address
Definition bl0906.h:4
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
Definition helpers.h:411
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:119
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:35
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:44
bool write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const
Definition i2c.cpp:62
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:30
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:26
bool read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len)
Definition i2c.cpp:54
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:95
I2CRegister16 & operator|=(uint8_t value)
overloads the compound |= operator.
Definition i2c.cpp:100
I2CDevice * parent_
I2CDevice object pointer.
Definition i2c.h:122
uint8_t get() const
returns the register value
Definition i2c.cpp:106
I2CRegister16 & operator=(uint8_t value)
overloads the = operator.
Definition i2c.cpp:91
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:79
uint8_t get() const
returns the register value
Definition i2c.cpp:85
I2CRegister & operator&=(uint8_t value)
overloads the compound &= operator.
Definition i2c.cpp:74
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:70
uint16_t i2ctohs(uint16_t i2cshort)
Definition i2c.h:128
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition i2c_bus.h:15
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:17
@ ERROR_UNKNOWN
miscellaneous I2C error during execution
Definition i2c_bus.h:23
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:584
std::string size_t len
Definition helpers.h:692
void IRAM_ATTR HOT arch_feed_wdt()
Definition core.cpp:47