ESPHome  2024.7.0
i2c.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "i2c_bus.h"
4 #include "esphome/core/helpers.h"
6 #include <array>
7 #include <vector>
8 
9 namespace esphome {
10 namespace i2c {
11 
12 #define LOG_I2C_DEVICE(this) ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
13 
14 class I2CDevice; // forward declaration
15 
33 class I2CRegister {
34  public:
38  I2CRegister &operator=(uint8_t value);
39 
43  I2CRegister &operator&=(uint8_t value);
44 
48  I2CRegister &operator|=(uint8_t value);
49 
52  explicit operator uint8_t() const { return get(); }
53 
56  uint8_t get() const;
57 
58  protected:
59  friend class I2CDevice;
60 
65  I2CRegister(I2CDevice *parent, uint8_t a_register) : parent_(parent), register_(a_register) {}
66 
68  uint8_t register_;
69 };
70 
89  public:
93  I2CRegister16 &operator=(uint8_t value);
94 
98  I2CRegister16 &operator&=(uint8_t value);
99 
103  I2CRegister16 &operator|=(uint8_t value);
104 
107  explicit operator uint8_t() const { return get(); }
108 
111  uint8_t get() const;
112 
113  protected:
114  friend class I2CDevice;
115 
120  I2CRegister16(I2CDevice *parent, uint16_t a_register) : parent_(parent), register_(a_register) {}
121 
123  uint16_t register_;
124 };
125 
126 // like ntohs/htons but without including networking headers.
127 // ("i2c" byte order is big-endian)
128 inline uint16_t i2ctohs(uint16_t i2cshort) { return convert_big_endian(i2cshort); }
129 inline uint16_t htoi2cs(uint16_t hostshort) { return convert_big_endian(hostshort); }
130 
133 class I2CDevice {
134  public:
136  I2CDevice() = default;
137 
140  void set_i2c_address(uint8_t address) { address_ = address; }
141 
144  void set_i2c_bus(I2CBus *bus) { bus_ = bus; }
145 
149  I2CRegister reg(uint8_t a_register) { return {this, a_register}; }
150 
154  I2CRegister16 reg16(uint16_t a_register) { return {this, a_register}; }
155 
160  ErrorCode read(uint8_t *data, size_t len) { return bus_->read(address_, data, len); }
161 
169  ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop = true);
170 
178  ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop = true);
179 
186  ErrorCode write(const uint8_t *data, size_t len, bool stop = true) { return bus_->write(address_, data, len, stop); }
187 
195  ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop = true);
196 
204  ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len, bool stop = true);
205 
211 
212  bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len) {
213  return read_register(a_register, data, len) == ERROR_OK;
214  }
215 
216  bool read_bytes_raw(uint8_t *data, uint8_t len) { return read(data, len) == ERROR_OK; }
217 
218  template<size_t N> optional<std::array<uint8_t, N>> read_bytes(uint8_t a_register) {
219  std::array<uint8_t, N> res;
220  if (!this->read_bytes(a_register, res.data(), N)) {
221  return {};
222  }
223  return res;
224  }
226  std::array<uint8_t, N> res;
227  if (!this->read_bytes_raw(res.data(), N)) {
228  return {};
229  }
230  return res;
231  }
232 
233  bool read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len);
234 
235  bool read_byte(uint8_t a_register, uint8_t *data, bool stop = true) {
236  return read_register(a_register, data, 1, stop) == ERROR_OK;
237  }
238 
239  optional<uint8_t> read_byte(uint8_t a_register) {
240  uint8_t data;
241  if (!this->read_byte(a_register, &data))
242  return {};
243  return data;
244  }
245 
246  bool read_byte_16(uint8_t a_register, uint16_t *data) { return read_bytes_16(a_register, data, 1); }
247 
248  bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop = true) {
249  return write_register(a_register, data, len, stop) == ERROR_OK;
250  }
251 
252  bool write_bytes(uint8_t a_register, const std::vector<uint8_t> &data) {
253  return write_bytes(a_register, data.data(), data.size());
254  }
255 
256  template<size_t N> bool write_bytes(uint8_t a_register, const std::array<uint8_t, N> &data) {
257  return write_bytes(a_register, data.data(), data.size());
258  }
259 
260  bool write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len);
261 
262  bool write_byte(uint8_t a_register, uint8_t data, bool stop = true) {
263  return write_bytes(a_register, &data, 1, stop);
264  }
265 
266  bool write_byte_16(uint8_t a_register, uint16_t data) { return write_bytes_16(a_register, &data, 1); }
267 
268  protected:
269  uint8_t address_{0x00};
270  I2CBus *bus_{nullptr};
271 };
272 
273 } // namespace i2c
274 } // namespace esphome
optional< std::array< uint8_t, N > > read_bytes(uint8_t a_register)
Definition: i2c.h:218
I2CDevice * parent_
I2CDevice object pointer.
Definition: i2c.h:122
I2CRegister(I2CDevice *parent, uint8_t a_register)
protected constructor that stores the owning object and the register address.
Definition: i2c.h:65
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition: i2c.h:246
uint16_t i2ctohs(uint16_t i2cshort)
Definition: i2c.h:128
friend class I2CDevice
Definition: i2c.h:59
uint16_t register_
the internal 16 bits address of the register
Definition: i2c.h:123
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition: i2c.h:149
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition: i2c.h:160
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition: i2c.h:225
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition: i2c.h:212
uint8_t register_
the internal address of the register
Definition: i2c.h:68
bool read_bytes_raw(uint8_t *data, uint8_t len)
Definition: i2c.h:216
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition: i2c.h:186
uint16_t htoi2cs(uint16_t hostshort)
Definition: i2c.h:129
I2CRegister & operator|=(uint8_t value)
overloads the compound |= operator.
Definition: i2c.cpp:69
bool write_bytes(uint8_t a_register, const std::array< uint8_t, N > &data)
Definition: i2c.h:256
No error found during execution of method.
Definition: i2c_bus.h:13
This Class provides the methods to read and write bytes from an I2CBus.
Definition: i2c_bus.h:40
constexpr14 T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order...
Definition: helpers.h:239
optional< uint8_t > read_byte(uint8_t a_register)
Definition: i2c.h:239
bool write_bytes(uint8_t a_register, const std::vector< uint8_t > &data)
Definition: i2c.h:252
I2CRegister16 reg16(uint16_t a_register)
calls the I2CRegister16 constructor
Definition: i2c.h:154
std::string size_t len
Definition: helpers.h:292
This class is used to create I2CRegister objects that act as proxies to read/write internal registers...
Definition: i2c.h:33
I2CRegister16(I2CDevice *parent, uint16_t a_register)
protected constructor that store the owning object and the register address.
Definition: i2c.h:120
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
This class is used to create I2CRegister16 objects that act as proxies to read/write internal registe...
Definition: i2c.h:88
I2CRegister & operator &=(uint8_t value)
overloads the compound &= operator.
I2CDevice * parent_
I2CDevice object pointer.
Definition: i2c.h:67
I2CRegister & operator=(uint8_t value)
overloads the = operator.
Definition: i2c.cpp:60
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition: i2c_bus.h:11
bool write_byte_16(uint8_t a_register, uint16_t data)
Definition: i2c.h:266
void set_i2c_bus(I2CBus *bus)
we store the pointer to the I2CBus to use
Definition: i2c.h:144
This Class provides the methods to read/write bytes from/to an i2c device.
Definition: i2c.h:133
void set_i2c_address(uint8_t address)
We store the address of the device on the bus.
Definition: i2c.h:140
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:248