ESPHome 2026.3.0-dev
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::i2c {
9
10static const char *const TAG = "i2c";
11
13 for (uint8_t address = 8; address != 120; address++) {
14 auto err = write_readv(address, nullptr, 0, nullptr, 0);
15 if (err == ERROR_OK) {
16 scan_results_.emplace_back(address, true);
17 } else if (err == ERROR_UNKNOWN) {
18 scan_results_.emplace_back(address, false);
19 }
20 // it takes 16sec to scan on nrf52. It prevents board reset.
22 }
23}
24
25ErrorCode I2CDevice::read_register(uint8_t a_register, uint8_t *data, size_t len) {
26 return bus_->write_readv(this->address_, &a_register, 1, data, len);
27}
28
29ErrorCode I2CDevice::read_register16(uint16_t a_register, uint8_t *data, size_t len) {
30 a_register = convert_big_endian(a_register);
31 return bus_->write_readv(this->address_, reinterpret_cast<const uint8_t *>(&a_register), 2, data, len);
32}
33
34ErrorCode I2CDevice::write_register(uint8_t a_register, const uint8_t *data, size_t len) const {
35 SmallBufferWithHeapFallback<17> buffer_alloc(len + 1); // Most I2C writes are <= 16 bytes
36 uint8_t *buffer = buffer_alloc.get();
37
38 buffer[0] = a_register;
39 std::copy(data, data + len, buffer + 1);
40 return this->bus_->write_readv(this->address_, buffer, len + 1, nullptr, 0);
41}
42
43ErrorCode I2CDevice::write_register16(uint16_t a_register, const uint8_t *data, size_t len) const {
44 SmallBufferWithHeapFallback<18> buffer_alloc(len + 2); // Most I2C writes are <= 16 bytes + 2 for register
45 uint8_t *buffer = buffer_alloc.get();
46
47 buffer[0] = a_register >> 8;
48 buffer[1] = a_register;
49 std::copy(data, data + len, buffer + 2);
50 return this->bus_->write_readv(this->address_, buffer, len + 2, nullptr, 0);
51}
52
53bool I2CDevice::read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len) {
54 if (read_register(a_register, reinterpret_cast<uint8_t *>(data), len * 2) != ERROR_OK)
55 return false;
56 for (size_t i = 0; i < len; i++)
57 data[i] = i2ctohs(data[i]);
58 return true;
59}
60
61bool I2CDevice::write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const {
62 // we have to copy in order to be able to change byte order
63 std::unique_ptr<uint16_t[]> temp{new uint16_t[len]};
64 for (size_t i = 0; i < len; i++)
65 temp[i] = htoi2cs(data[i]);
66 return write_register(a_register, reinterpret_cast<const uint8_t *>(temp.get()), len * 2) == ERROR_OK;
67}
68
70 this->parent_->write_register(this->register_, &value, 1);
71 return *this;
72}
74 value &= get();
75 this->parent_->write_register(this->register_, &value, 1);
76 return *this;
77}
79 value |= get();
80 this->parent_->write_register(this->register_, &value, 1);
81 return *this;
82}
83
84uint8_t I2CRegister::get() const {
85 uint8_t value = 0x00;
86 this->parent_->read_register(this->register_, &value, 1);
87 return value;
88}
89
91 this->parent_->write_register16(this->register_, &value, 1);
92 return *this;
93}
95 value &= get();
96 this->parent_->write_register16(this->register_, &value, 1);
97 return *this;
98}
100 value |= get();
101 this->parent_->write_register16(this->register_, &value, 1);
102 return *this;
103}
104
105uint8_t I2CRegister16::get() const {
106 uint8_t value = 0x00;
107 this->parent_->read_register16(this->register_, &value, 1);
108 return value;
109}
110
111} // namespace esphome::i2c
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:483
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:60
void i2c_scan_()
Scans the I2C bus for devices.
Definition i2c.cpp:12
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:34
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:43
bool write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len) const
Definition i2c.cpp:61
I2CBus * bus_
pointer to I2CBus instance
Definition i2c.h:271
uint8_t address_
store the address of the device on the bus
Definition i2c.h:270
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:29
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:25
bool read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len)
Definition i2c.cpp:53
This class is used to create I2CRegister16 objects that act as proxies to read/write internal registe...
Definition i2c.h:87
uint16_t register_
the internal 16 bits address of the register
Definition i2c.h:122
I2CRegister16 & operator&=(uint8_t value)
overloads the compound &= operator.
Definition i2c.cpp:94
I2CRegister16 & operator|=(uint8_t value)
overloads the compound |= operator.
Definition i2c.cpp:99
I2CDevice * parent_
I2CDevice object pointer.
Definition i2c.h:121
uint8_t get() const
returns the register value
Definition i2c.cpp:105
I2CRegister16 & operator=(uint8_t value)
overloads the = operator.
Definition i2c.cpp:90
This class is used to create I2CRegister objects that act as proxies to read/write internal registers...
Definition i2c.h:32
I2CRegister & operator|=(uint8_t value)
overloads the compound |= operator.
Definition i2c.cpp:78
uint8_t get() const
returns the register value
Definition i2c.cpp:84
I2CRegister & operator&=(uint8_t value)
overloads the compound &= operator.
Definition i2c.cpp:73
I2CDevice * parent_
I2CDevice object pointer.
Definition i2c.h:66
uint8_t register_
the internal address of the register
Definition i2c.h:67
I2CRegister & operator=(uint8_t value)
overloads the = operator.
Definition i2c.cpp:69
uint16_t i2ctohs(uint16_t i2cshort)
Definition i2c.h:127
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition i2c_bus.h:12
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14
@ ERROR_UNKNOWN
miscellaneous I2C error during execution
Definition i2c_bus.h:20
uint16_t htoi2cs(uint16_t hostshort)
Definition i2c.h:128
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:709
std::string size_t len
Definition helpers.h:817
void HOT arch_feed_wdt()
Definition core.cpp:48