ESPHome 2025.10.0-dev
Loading...
Searching...
No Matches
i2c_bus.h
Go to the documentation of this file.
1#pragma once
2#include <cstddef>
3#include <cstdint>
4#include <cstring>
5#include <memory>
6#include <utility>
7#include <vector>
8
10
11namespace esphome {
12namespace i2c {
13
15template<size_t STACK_SIZE> class SmallBufferWithHeapFallback {
16 public:
17 uint8_t *get(size_t size) {
18 if (size <= STACK_SIZE) {
19 return this->stack_buffer_;
20 }
21 this->heap_buffer_ = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
22 return this->heap_buffer_.get();
23 }
24
25 private:
26 uint8_t stack_buffer_[STACK_SIZE];
27 std::unique_ptr<uint8_t[]> heap_buffer_;
28};
29
42
44struct ReadBuffer {
45 uint8_t *data;
46 size_t len;
47};
48
51 const uint8_t *data;
52 size_t len;
53};
54
60class I2CBus {
61 public:
62 virtual ~I2CBus() = default;
63
74 virtual ErrorCode write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count, uint8_t *read_buffer,
75 size_t read_count) = 0;
76
77 // Legacy functions for compatibility
78
79 ErrorCode read(uint8_t address, uint8_t *buffer, size_t len) {
80 return this->write_readv(address, nullptr, 0, buffer, len);
81 }
82
83 ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len, bool stop = true) {
84 return this->write_readv(address, buffer, len, nullptr, 0);
85 }
86
87 ESPDEPRECATED("This method is deprecated and will be removed in ESPHome 2026.3.0. Use write_readv() instead.",
88 "2025.9.0")
89 ErrorCode readv(uint8_t address, ReadBuffer *read_buffers, size_t count) {
90 size_t total_len = 0;
91 for (size_t i = 0; i != count; i++) {
92 total_len += read_buffers[i].len;
93 }
94
96 uint8_t *buffer = buffer_alloc.get(total_len);
97
98 auto err = this->write_readv(address, nullptr, 0, buffer, total_len);
99 if (err != ERROR_OK)
100 return err;
101 size_t pos = 0;
102 for (size_t i = 0; i != count; i++) {
103 if (read_buffers[i].len != 0) {
104 std::memcpy(read_buffers[i].data, buffer + pos, read_buffers[i].len);
105 pos += read_buffers[i].len;
106 }
107 }
108 return ERROR_OK;
109 }
110
111 ESPDEPRECATED("This method is deprecated and will be removed in ESPHome 2026.3.0. Use write_readv() instead.",
112 "2025.9.0")
113 ErrorCode writev(uint8_t address, const WriteBuffer *write_buffers, size_t count, bool stop = true) {
114 size_t total_len = 0;
115 for (size_t i = 0; i != count; i++) {
116 total_len += write_buffers[i].len;
117 }
118
119 SmallBufferWithHeapFallback<128> buffer_alloc; // Most I2C writes are small
120 uint8_t *buffer = buffer_alloc.get(total_len);
121
122 size_t pos = 0;
123 for (size_t i = 0; i != count; i++) {
124 std::memcpy(buffer + pos, write_buffers[i].data, write_buffers[i].len);
125 pos += write_buffers[i].len;
126 }
127
128 return this->write_readv(address, buffer, total_len, nullptr, 0);
129 }
130
131 protected:
134 void i2c_scan_();
135 std::vector<std::pair<uint8_t, bool>> scan_results_;
136 bool scan_{false};
137};
138
139class InternalI2CBus : public I2CBus {
140 public:
143 virtual int get_port() const = 0;
144};
145
146} // namespace i2c
147} // namespace esphome
uint8_t address
Definition bl0906.h:4
This Class provides the methods to read and write bytes from an I2CBus.
Definition i2c_bus.h:60
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...
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
uint8_t * buffer
Definition i2c_bus.h:96
ReadBuffer size_t count
Definition i2c_bus.h:89
virtual ~I2CBus()=default
ESPDEPRECATED("This method is deprecated and will be removed in ESPHome 2026.3.0. Use write_readv() instead.", "2025.9.0") ErrorCode readv(uint8_t address
ReadBuffer * read_buffers
Definition i2c_bus.h:89
const WriteBuffer size_t bool stop
Definition i2c_bus.h:113
SmallBufferWithHeapFallback< 128 > buffer_alloc
Definition i2c_bus.h:95
const WriteBuffer * write_buffers
Definition i2c_bus.h:113
ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len, bool stop=true)
Definition i2c_bus.h:83
ESPDEPRECATED("This method is deprecated and will be removed in ESPHome 2026.3.0. Use write_readv() instead.", "2025.9.0") ErrorCode writev(uint8_t address
ErrorCode read(uint8_t address, uint8_t *buffer, size_t len)
Definition i2c_bus.h:79
virtual int get_port() const =0
Returns the I2C port number.
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large.
Definition i2c_bus.h:15
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition i2c_bus.h:31
@ ERROR_CRC
bytes received with a CRC error
Definition i2c_bus.h:40
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:33
@ ERROR_TOO_LARGE
requested a transfer larger than buffers can hold
Definition i2c_bus.h:38
@ ERROR_INVALID_ARGUMENT
method called invalid argument(s)
Definition i2c_bus.h:34
@ NO_ERROR
No error found during execution of method.
Definition i2c_bus.h:32
@ ERROR_TIMEOUT
timeout while waiting to receive bytes
Definition i2c_bus.h:36
@ 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
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:291
the ReadBuffer structure stores a pointer to a read buffer and its length
Definition i2c_bus.h:44
size_t len
length of the buffer
Definition i2c_bus.h:46
uint8_t * data
pointer to the read buffer
Definition i2c_bus.h:45
the WriteBuffer structure stores a pointer to a write buffer and its length
Definition i2c_bus.h:50
size_t len
length of the buffer
Definition i2c_bus.h:52
const uint8_t * data
pointer to the write buffer
Definition i2c_bus.h:51