M5UnitUnified 0.4.4 git rev:306ddd5
Loading...
Searching...
No Matches
adapter_i2c.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_COMPONENT_ADAPTER_I2C_HPP
11#define M5_UNIT_COMPONENT_ADAPTER_I2C_HPP
12
13#include "adapter_base.hpp"
14#include "pin.hpp"
15
16class TwoWire;
17
18namespace m5 {
19class I2C_Class;
20namespace unit {
21
26class AdapterI2C : public Adapter {
27public:
29 enum class ImplType : uint8_t {
30 Unknown,
31 TwoWire,
32 Bus,
33 I2CClass,
34 };
35
36 class I2CImpl : public Adapter::Impl {
37 public:
38 I2CImpl() = default;
39 I2CImpl(const uint8_t addr, const uint32_t clock) : Adapter::Impl(), _addr(addr), _clock(clock)
40 {
41 }
42
43 virtual ~I2CImpl() = default;
44
45 inline uint8_t address() const
46 {
47 return _addr;
48 }
49 inline virtual void setAddress(const uint8_t addr)
50 {
51 _addr = addr;
52 }
53
54 inline uint32_t clock() const
55 {
56 return _clock;
57 }
58
59 inline virtual void setClock(const uint32_t clock)
60 {
61 _clock = clock;
62 }
63
64 //
65 virtual int16_t scl() const
66 {
67 return -1;
68 }
69 virtual int16_t sda() const
70 {
71 return -1;
72 }
73
74 //
75 virtual bool begin()
76 {
77 return false;
78 }
79 virtual bool end()
80 {
81 return false;
82 }
83 virtual m5::hal::error::error_t wakeup()
84 {
85 return m5::hal::error::error_t::UNKNOWN_ERROR;
86 }
87
88 //
89 virtual I2CImpl* duplicate(const uint8_t addr)
90 {
91 return new I2CImpl(addr, _clock);
92 }
93
95 virtual ImplType implType() const
96 {
97 return ImplType::Unknown;
98 }
99
100 virtual TwoWire* getWire()
101 {
102 return nullptr;
103 }
104 virtual m5::hal::bus::Bus* getBus()
105 {
106 return nullptr;
107 }
108 virtual m5::I2C_Class* getI2CClass()
109 {
110 return nullptr;
111 }
112
113 protected:
114 uint8_t _addr{};
115 uint32_t _clock{100 * 1000U};
116 };
117
118 //
119#if defined(ARDUINO)
120 class WireImpl : public I2CImpl {
121 public:
122 WireImpl(TwoWire& wire, const uint8_t addr, const uint32_t clock);
123 inline virtual ImplType implType() const override
124 {
125 return ImplType::TwoWire;
126 }
127 inline virtual TwoWire* getWire() override
128 {
129 return _wire;
130 }
131 inline virtual int16_t scl() const override
132 {
133 return _scl;
134 }
135 inline virtual int16_t sda() const override
136 {
137 return _sda;
138 }
139 virtual bool begin() override;
140 virtual bool end() override;
141 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len) override;
142 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len,
143 const uint32_t stop) override;
144 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t reg, const uint8_t* data, const size_t len,
145 const uint32_t stop) override;
146 virtual m5::hal::error::error_t writeWithTransaction(const uint16_t reg, const uint8_t* data, const size_t len,
147 const uint32_t stop) override;
148 virtual I2CImpl* duplicate(const uint8_t addr) override;
149 virtual m5::hal::error::error_t generalCall(const uint8_t* data, const size_t len) override;
150 virtual m5::hal::error::error_t wakeup() override;
151
152 protected:
153 m5::hal::error::error_t write_with_transaction(const uint8_t addr, const uint8_t* data, const size_t len,
154 const uint32_t stop);
155
156 private:
157 TwoWire* _wire{};
158 int16_t _sda{}, _scl{};
159 };
160#endif
161
162 class BusImpl : public I2CImpl {
163 public:
164 BusImpl(m5::hal::bus::Bus* bus, const uint8_t addr, const uint32_t clock);
165 inline virtual ImplType implType() const override
166 {
167 return ImplType::Bus;
168 }
169 inline virtual m5::hal::bus::Bus* getBus() override
170 {
171 return _bus;
172 }
173 inline virtual int16_t scl() const override
174 {
175 return _scl;
176 }
177 inline virtual int16_t sda() const override
178 {
179 return _sda;
180 }
181
182 inline virtual void setAddress(const uint8_t addr) override
183 {
184 I2CImpl::setAddress(addr);
185 _access_cfg.i2c_addr = addr;
186 }
187 inline virtual void setClock(const uint32_t clock) override
188 {
189 I2CImpl::setClock(clock);
190 _access_cfg.freq = clock;
191 }
192 virtual bool begin() override
193 {
194 return true;
195 }
196 virtual bool end() override
197 {
198 return true;
199 }
200 virtual I2CImpl* duplicate(const uint8_t addr) override;
201 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len) override;
202 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len,
203 const uint32_t stop) override;
204
205 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t reg, const uint8_t* data, const size_t len,
206 const uint32_t stop) override;
207 virtual m5::hal::error::error_t writeWithTransaction(const uint16_t reg, const uint8_t* data, const size_t len,
208 const uint32_t stop) override;
209 virtual m5::hal::error::error_t generalCall(const uint8_t* data, const size_t len) override;
210 virtual m5::hal::error::error_t wakeup() override;
211
212 protected:
213 m5::hal::error::error_t write_with_transaction(const m5::hal::bus::I2CMasterAccessConfig& cfg,
214 const uint8_t* data, const size_t len, const uint32_t stop);
215
216 private:
217 m5::hal::bus::Bus* _bus{};
218 m5::hal::bus::I2CMasterAccessConfig _access_cfg{};
219 int16_t _sda{-1}, _scl{-1};
220 };
221
222 class I2CClassImpl : public I2CImpl {
223 public:
224 I2CClassImpl(m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock);
225 inline virtual ImplType implType() const override
226 {
227 return ImplType::I2CClass;
228 }
229 inline virtual m5::I2C_Class* getI2CClass() override
230 {
231 return _i2c;
232 }
233 inline virtual int16_t scl() const override
234 {
235 return _scl;
236 }
237 inline virtual int16_t sda() const override
238 {
239 return _sda;
240 }
241 virtual bool begin() override;
242 virtual bool end() override;
243 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len) override;
244 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len,
245 const uint32_t stop) override;
246 virtual m5::hal::error::error_t writeWithTransaction(const uint8_t reg, const uint8_t* data, const size_t len,
247 const uint32_t stop) override;
248 virtual m5::hal::error::error_t writeWithTransaction(const uint16_t reg, const uint8_t* data, const size_t len,
249 const uint32_t stop) override;
250 virtual I2CImpl* duplicate(const uint8_t addr) override;
251 virtual m5::hal::error::error_t generalCall(const uint8_t* data, const size_t len) override;
252 virtual m5::hal::error::error_t wakeup() override;
253
254 private:
255 m5::I2C_Class* _i2c{};
256 int16_t _sda{-1}, _scl{-1};
257 bool _in_transaction{false};
258 };
259
260#if defined(ARDUINO)
261 AdapterI2C(TwoWire& wire, uint8_t addr, const uint32_t clock);
262#endif
263 AdapterI2C(m5::hal::bus::Bus* bus, const uint8_t addr, const uint32_t clock);
264 AdapterI2C(m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock);
265 AdapterI2C(m5::hal::bus::Bus& bus, const uint8_t addr, const uint32_t clock) : AdapterI2C(&bus, addr, clock)
266 {
267 }
268
269 inline I2CImpl* impl()
270 {
271 return static_cast<I2CImpl*>(_impl.get());
272 }
273 inline const I2CImpl* impl() const
274 {
275 return static_cast<I2CImpl*>(_impl.get());
276 }
277
278 inline uint8_t address() const
279 {
280 return impl()->address();
281 }
282 inline void setAddress(const uint8_t addr)
283 {
284 impl()->setAddress(addr);
285 }
286
287 inline uint32_t clock() const
288 {
289 return impl()->clock();
290 }
291
292 inline void setClock(const uint32_t clock)
293 {
294 impl()->setClock(clock);
295 }
296
298 inline ImplType implType() const
299 {
300 return impl()->implType();
301 }
302
303 inline int16_t scl() const
304 {
305 return impl()->scl();
306 }
307 inline int16_t sda() const
308 {
309 return impl()->sda();
310 }
311
312 virtual Adapter* duplicate(const uint8_t addr) override;
313
318 inline bool begin()
319 {
320 return impl()->begin();
321 }
322 inline bool end()
323 {
324 return impl()->end();
325 }
326 bool pushPin();
327 bool popPin();
329
330protected:
331 AdapterI2C() : Adapter(Adapter::Type::I2C, new I2CImpl())
332 {
333 }
334
335protected:
336 gpio::pin_backup_t _backupSCL{-1}, _backupSDA{-1};
337};
338
339} // namespace unit
340} // namespace m5
341#endif
Adapter base.
Definition adapter_base.hpp:35
Definition adapter_i2c.hpp:162
virtual ImplType implType() const override
Gets the implementation type.
Definition adapter_i2c.hpp:165
Definition adapter_i2c.hpp:222
virtual ImplType implType() const override
Gets the implementation type.
Definition adapter_i2c.hpp:225
Definition adapter_i2c.hpp:36
virtual ImplType implType() const
Gets the implementation type.
Definition adapter_i2c.hpp:95
ImplType
I2C implementation type.
Definition adapter_i2c.hpp:29
@ I2CClass
m5::I2C_Class (m5gfx::i2c)
@ Bus
M5HAL Bus (including SoftwareI2C)
ImplType implType() const
Gets the I2C implementation type.
Definition adapter_i2c.hpp:298
Top level namespace of M5stack.
Definition test_helper.hpp:20
Unit-related namespace.
PIN settings save/restore.