ESPHome  2023.11.6
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;
15 class I2CRegister {
16  public:
17  I2CRegister &operator=(uint8_t value);
18  I2CRegister &operator&=(uint8_t value);
19  I2CRegister &operator|=(uint8_t value);
20 
21  explicit operator uint8_t() const { return get(); }
22 
23  uint8_t get() const;
24 
25  protected:
26  friend class I2CDevice;
27 
28  I2CRegister(I2CDevice *parent, uint8_t a_register) : parent_(parent), register_(a_register) {}
29 
31  uint8_t register_;
32 };
33 
35  public:
36  I2CRegister16 &operator=(uint8_t value);
37  I2CRegister16 &operator&=(uint8_t value);
38  I2CRegister16 &operator|=(uint8_t value);
39 
40  explicit operator uint8_t() const { return get(); }
41 
42  uint8_t get() const;
43 
44  protected:
45  friend class I2CDevice;
46 
47  I2CRegister16(I2CDevice *parent, uint16_t a_register) : parent_(parent), register_(a_register) {}
48 
50  uint16_t register_;
51 };
52 
53 // like ntohs/htons but without including networking headers.
54 // ("i2c" byte order is big-endian)
55 inline uint16_t i2ctohs(uint16_t i2cshort) { return convert_big_endian(i2cshort); }
56 inline uint16_t htoi2cs(uint16_t hostshort) { return convert_big_endian(hostshort); }
57 
58 class I2CDevice {
59  public:
60  I2CDevice() = default;
61 
62  void set_i2c_address(uint8_t address) { address_ = address; }
63  void set_i2c_bus(I2CBus *bus) { bus_ = bus; }
64 
65  I2CRegister reg(uint8_t a_register) { return {this, a_register}; }
66  I2CRegister16 reg16(uint16_t a_register) { return {this, a_register}; }
67 
68  ErrorCode read(uint8_t *data, size_t len) { return bus_->read(address_, data, len); }
69  ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop = true);
70  ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop = true);
71 
72  ErrorCode write(const uint8_t *data, uint8_t len, bool stop = true) { return bus_->write(address_, data, len, stop); }
73  ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop = true);
74  ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len, bool stop = true);
75 
76  // Compat APIs
77 
78  bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len) {
79  return read_register(a_register, data, len) == ERROR_OK;
80  }
81  bool read_bytes_raw(uint8_t *data, uint8_t len) { return read(data, len) == ERROR_OK; }
82 
83  template<size_t N> optional<std::array<uint8_t, N>> read_bytes(uint8_t a_register) {
84  std::array<uint8_t, N> res;
85  if (!this->read_bytes(a_register, res.data(), N)) {
86  return {};
87  }
88  return res;
89  }
91  std::array<uint8_t, N> res;
92  if (!this->read_bytes_raw(res.data(), N)) {
93  return {};
94  }
95  return res;
96  }
97 
98  bool read_bytes_16(uint8_t a_register, uint16_t *data, uint8_t len);
99 
100  bool read_byte(uint8_t a_register, uint8_t *data, bool stop = true) {
101  return read_register(a_register, data, 1, stop) == ERROR_OK;
102  }
103 
104  optional<uint8_t> read_byte(uint8_t a_register) {
105  uint8_t data;
106  if (!this->read_byte(a_register, &data))
107  return {};
108  return data;
109  }
110 
111  bool read_byte_16(uint8_t a_register, uint16_t *data) { return read_bytes_16(a_register, data, 1); }
112 
113  bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop = true) {
114  return write_register(a_register, data, len, stop) == ERROR_OK;
115  }
116 
117  bool write_bytes(uint8_t a_register, const std::vector<uint8_t> &data) {
118  return write_bytes(a_register, data.data(), data.size());
119  }
120 
121  template<size_t N> bool write_bytes(uint8_t a_register, const std::array<uint8_t, N> &data) {
122  return write_bytes(a_register, data.data(), data.size());
123  }
124 
125  bool write_bytes_16(uint8_t a_register, const uint16_t *data, uint8_t len);
126 
127  bool write_byte(uint8_t a_register, uint8_t data, bool stop = true) {
128  return write_bytes(a_register, &data, 1, stop);
129  }
130 
131  bool write_byte_16(uint8_t a_register, uint16_t data) { return write_bytes_16(a_register, &data, 1); }
132 
133  protected:
134  uint8_t address_{0x00};
135  I2CBus *bus_{nullptr};
136 };
137 
138 } // namespace i2c
139 } // namespace esphome
optional< std::array< uint8_t, N > > read_bytes(uint8_t a_register)
Definition: i2c.h:83
I2CDevice * parent_
Definition: i2c.h:49
I2CRegister(I2CDevice *parent, uint8_t a_register)
Definition: i2c.h:28
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:100
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition: i2c.h:111
uint16_t i2ctohs(uint16_t i2cshort)
Definition: i2c.h:55
friend class I2CDevice
Definition: i2c.h:26
I2CRegister reg(uint8_t a_register)
Definition: i2c.h:65
ErrorCode read(uint8_t *data, size_t len)
Definition: i2c.h:68
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition: i2c.h:90
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Definition: i2c.h:78
bool read_bytes_raw(uint8_t *data, uint8_t len)
Definition: i2c.h:81
uint16_t htoi2cs(uint16_t hostshort)
Definition: i2c.h:56
I2CRegister & operator|=(uint8_t value)
Definition: i2c.cpp:69
bool write_bytes(uint8_t a_register, const std::array< uint8_t, N > &data)
Definition: i2c.h:121
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
ErrorCode write(const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:72
optional< uint8_t > read_byte(uint8_t a_register)
Definition: i2c.h:104
bool write_bytes(uint8_t a_register, const std::vector< uint8_t > &data)
Definition: i2c.h:117
I2CRegister16 reg16(uint16_t a_register)
Definition: i2c.h:66
std::string size_t len
Definition: helpers.h:292
I2CRegister16(I2CDevice *parent, uint16_t a_register)
Definition: i2c.h:47
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:127
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
I2CRegister & operator &=(uint8_t value)
I2CDevice * parent_
Definition: i2c.h:30
I2CRegister & operator=(uint8_t value)
Definition: i2c.cpp:60
bool write_byte_16(uint8_t a_register, uint16_t data)
Definition: i2c.h:131
void set_i2c_bus(I2CBus *bus)
Definition: i2c.h:63
void set_i2c_address(uint8_t address)
Definition: i2c.h:62
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:113