10#ifndef M5_UNIT_COMPONENT_ADAPTER_I2C_HPP
11#define M5_UNIT_COMPONENT_ADAPTER_I2C_HPP
15#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
16#include <driver/i2c_master.h>
17#elif defined(ESP_PLATFORM)
18#include <driver/i2c.h>
32class AdapterI2C :
public Adapter {
40#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
42#elif defined(ESP_PLATFORM)
56 inline uint8_t address()
const
60 inline virtual void setAddress(
const uint8_t addr)
65 inline uint32_t clock()
const
70 inline virtual void setClock(
const uint32_t clock)
77 virtual int16_t
port()
const
81 virtual int16_t scl()
const
85 virtual int16_t sda()
const
99 virtual m5::hal::error::error_t wakeup()
101 return m5::hal::error::error_t::UNKNOWN_ERROR;
105 virtual I2CImpl* duplicate(
const uint8_t addr)
107 return new I2CImpl(addr, _clock);
120 virtual m5::hal::bus::Bus* getBus()
124 virtual m5::I2C_Class* getI2CClass()
131 uint32_t _clock{100 * 1000U};
134#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
135 class ESPIDFMasterBusImpl :
public I2CImpl {
137 ESPIDFMasterBusImpl(i2c_master_bus_handle_t bus,
const i2c_port_t port,
const gpio_num_t sda,
138 const gpio_num_t scl,
const uint8_t addr,
const uint32_t clock);
139 inline virtual ImplType implType()
const override
141 return ImplType::ESPIDFMasterBus;
143 inline virtual int16_t port()
const override
147 inline virtual int16_t scl()
const override
151 inline virtual int16_t sda()
const override
155 inline virtual void setAddress(
const uint8_t addr)
override
160 I2CImpl::setAddress(addr);
162 virtual void setClock(
const uint32_t clock)
override;
163 virtual bool begin()
override;
164 virtual bool end()
override;
165 virtual I2CImpl* duplicate(
const uint8_t addr)
override;
166 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data,
const size_t len)
override;
167 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t* data,
const size_t len,
168 const uint32_t stop)
override;
169 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t reg,
const uint8_t* data,
const size_t len,
170 const uint32_t stop)
override;
171 virtual m5::hal::error::error_t writeWithTransaction(
const uint16_t reg,
const uint8_t* data,
const size_t len,
172 const uint32_t stop)
override;
173 virtual m5::hal::error::error_t generalCall(
const uint8_t* data,
const size_t len)
override;
174 virtual m5::hal::error::error_t wakeup()
override;
177 m5::hal::error::error_t ensure_device();
178 m5::hal::error::error_t transmit(
const uint8_t* data,
const size_t len);
179 void set_pending_write(
const uint8_t* data,
const size_t len);
182 i2c_master_bus_handle_t _bus{};
183 i2c_master_dev_handle_t _dev{};
184 std::vector<uint8_t> _pending_write{};
185 int16_t _port{-1}, _sda{-1}, _scl{-1};
187#elif defined(ESP_PLATFORM)
188 class ESPIDFLegacyBusImpl :
public I2CImpl {
190 ESPIDFLegacyBusImpl(
const i2c_port_t port,
const gpio_num_t sda,
const gpio_num_t scl,
const uint8_t addr,
191 const uint32_t clock);
192 inline virtual ImplType implType()
const override
194 return ImplType::ESPIDFLegacyBus;
196 inline virtual int16_t port()
const override
200 inline virtual int16_t scl()
const override
204 inline virtual int16_t sda()
const override
208 inline virtual void setClock(
const uint32_t clock)
override
210 if (_clock != clock) {
211 I2CImpl::setClock(clock);
215 virtual bool begin()
override;
216 virtual bool end()
override;
217 virtual I2CImpl* duplicate(
const uint8_t addr)
override;
218 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data,
const size_t len)
override;
219 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t* data,
const size_t len,
220 const uint32_t stop)
override;
221 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t reg,
const uint8_t* data,
const size_t len,
222 const uint32_t stop)
override;
223 virtual m5::hal::error::error_t writeWithTransaction(
const uint16_t reg,
const uint8_t* data,
const size_t len,
224 const uint32_t stop)
override;
225 virtual m5::hal::error::error_t generalCall(
const uint8_t* data,
const size_t len)
override;
226 virtual m5::hal::error::error_t wakeup()
override;
232 int start_setup{}, start_hold{};
233 int stop_setup{}, stop_hold{};
234 int sample{}, hold{};
239 void restore_timing()
const;
240 m5::hal::error::error_t result_of(
const esp_err_t err);
241 m5::hal::error::error_t write_with_transaction(
const uint8_t addr,
const uint8_t* data,
const size_t len,
242 const uint32_t stop);
245 i2c_port_t _port{I2C_NUM_0};
246 int16_t _sda{-1}, _scl{-1};
253 class WireImpl :
public I2CImpl {
255 WireImpl(TwoWire& wire,
const uint8_t addr,
const uint32_t clock);
256 inline virtual ImplType implType()
const override
258 return ImplType::TwoWire;
260 inline virtual TwoWire* getWire()
override
264 inline virtual int16_t port()
const override
268 inline virtual int16_t scl()
const override
272 inline virtual int16_t sda()
const override
276 virtual bool begin()
override;
277 virtual bool end()
override;
278 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data,
const size_t len)
override;
279 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t* data,
const size_t len,
280 const uint32_t stop)
override;
281 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t reg,
const uint8_t* data,
const size_t len,
282 const uint32_t stop)
override;
283 virtual m5::hal::error::error_t writeWithTransaction(
const uint16_t reg,
const uint8_t* data,
const size_t len,
284 const uint32_t stop)
override;
285 virtual I2CImpl* duplicate(
const uint8_t addr)
override;
286 virtual m5::hal::error::error_t generalCall(
const uint8_t* data,
const size_t len)
override;
287 virtual m5::hal::error::error_t wakeup()
override;
290 m5::hal::error::error_t write_with_transaction(
const uint8_t addr,
const uint8_t* data,
const size_t len,
291 const uint32_t stop);
295 int16_t _port{}, _sda{}, _scl{};
301 BusImpl(m5::hal::bus::Bus* bus,
const uint8_t addr,
const uint32_t clock);
306 inline virtual m5::hal::bus::Bus* getBus()
override
310 inline virtual int16_t scl()
const override
314 inline virtual int16_t sda()
const override
319 inline virtual void setAddress(
const uint8_t addr)
override
321 I2CImpl::setAddress(addr);
322 _access_cfg.i2c_addr = addr;
324 inline virtual void setClock(
const uint32_t clock)
override
326 I2CImpl::setClock(clock);
327 _access_cfg.freq = clock;
329 virtual bool begin()
override
333 virtual bool end()
override
337 virtual I2CImpl* duplicate(
const uint8_t addr)
override;
338 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data,
const size_t len)
override;
339 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t* data,
const size_t len,
340 const uint32_t stop)
override;
342 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t reg,
const uint8_t* data,
const size_t len,
343 const uint32_t stop)
override;
344 virtual m5::hal::error::error_t writeWithTransaction(
const uint16_t reg,
const uint8_t* data,
const size_t len,
345 const uint32_t stop)
override;
346 virtual m5::hal::error::error_t generalCall(
const uint8_t* data,
const size_t len)
override;
347 virtual m5::hal::error::error_t wakeup()
override;
350 m5::hal::error::error_t write_with_transaction(
const m5::hal::bus::I2CMasterAccessConfig& cfg,
351 const uint8_t* data,
const size_t len,
const uint32_t stop);
354 m5::hal::bus::Bus* _bus{};
355 m5::hal::bus::I2CMasterAccessConfig _access_cfg{};
356 int16_t _sda{-1}, _scl{-1};
361 I2CClassImpl(m5::I2C_Class& i2c,
const uint8_t addr,
const uint32_t clock);
366 inline virtual m5::I2C_Class* getI2CClass()
override
370 inline virtual int16_t
port()
const override
374 inline virtual int16_t scl()
const override
378 inline virtual int16_t sda()
const override
382 virtual bool begin()
override;
383 virtual bool end()
override;
384 virtual m5::hal::error::error_t readWithTransaction(uint8_t* data,
const size_t len)
override;
385 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t* data,
const size_t len,
386 const uint32_t stop)
override;
387 virtual m5::hal::error::error_t writeWithTransaction(
const uint8_t reg,
const uint8_t* data,
const size_t len,
388 const uint32_t stop)
override;
389 virtual m5::hal::error::error_t writeWithTransaction(
const uint16_t reg,
const uint8_t* data,
const size_t len,
390 const uint32_t stop)
override;
391 virtual I2CImpl* duplicate(
const uint8_t addr)
override;
392 virtual m5::hal::error::error_t generalCall(
const uint8_t* data,
const size_t len)
override;
393 virtual m5::hal::error::error_t wakeup()
override;
396 m5::I2C_Class* _i2c{};
397 int16_t _port{-1}, _sda{-1}, _scl{-1};
398 bool _in_transaction{
false};
402 AdapterI2C(
TwoWire& wire, uint8_t addr,
const uint32_t clock);
404 AdapterI2C(m5::hal::bus::Bus* bus,
const uint8_t addr,
const uint32_t clock);
405 AdapterI2C(m5::I2C_Class& i2c,
const uint8_t addr,
const uint32_t clock);
406#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
407 AdapterI2C(i2c_master_bus_handle_t bus,
const uint8_t addr,
const uint32_t clock);
408 AdapterI2C(i2c_master_bus_handle_t bus,
const i2c_port_t
port,
const gpio_num_t sda,
const gpio_num_t scl,
409 const uint8_t addr,
const uint32_t clock);
410#elif defined(ESP_PLATFORM)
411 AdapterI2C(
const i2c_port_t
port,
const gpio_num_t sda,
const gpio_num_t scl,
const uint8_t addr,
412 const uint32_t clock);
414 AdapterI2C(m5::hal::bus::Bus& bus,
const uint8_t addr,
const uint32_t clock) : AdapterI2C(&bus, addr, clock)
418 inline I2CImpl* impl()
420 return static_cast<I2CImpl*
>(_impl.get());
422 inline const I2CImpl* impl()
const
424 return static_cast<I2CImpl*
>(_impl.get());
427 inline uint8_t address()
const
429 return impl()->address();
431 inline void setAddress(
const uint8_t addr)
433 impl()->setAddress(addr);
436 inline uint32_t clock()
const
438 return impl()->clock();
441 inline void setClock(
const uint32_t clock)
443 impl()->setClock(clock);
455 return impl()->
port();
457 inline int16_t scl()
const
459 return impl()->scl();
461 inline int16_t sda()
const
463 return impl()->sda();
474 return impl()->begin();
478 return impl()->end();
512 gpio::pin_backup_t _backupSCL{-1}, _backupSDA{-1};
Implementation base class (Pimpl pattern)
Definition adapter_base.hpp:37
Adapter()
Default constructor (creates Unknown type adapter)
Definition adapter_base.hpp:137
Type
Adapter type.
Definition adapter_base.hpp:28
Definition adapter_i2c.hpp:299
virtual ImplType implType() const override
Gets the implementation type.
Definition adapter_i2c.hpp:302
Definition adapter_i2c.hpp:359
virtual ImplType implType() const override
Gets the implementation type.
Definition adapter_i2c.hpp:362
virtual int16_t port() const override
I2C port number, or -1 if unknown.
Definition adapter_i2c.hpp:370
Definition adapter_i2c.hpp:47
virtual int16_t port() const
I2C port number, or -1 if unknown.
Definition adapter_i2c.hpp:77
virtual ImplType implType() const
Gets the implementation type.
Definition adapter_i2c.hpp:111
virtual Adapter * duplicate(const uint8_t addr) override
Create a duplicate adapter with a different address.
Definition adapter_i2c.cpp:1037
ImplType
I2C implementation type.
Definition adapter_i2c.hpp:35
@ I2CClass
m5::I2C_Class (m5gfx::i2c)
@ TwoWire
Arduino TwoWire.
@ Bus
M5HAL Bus (including SoftwareI2C)
bool releasePins()
Detach SDA/SCL from the I2C controller and make them GPIO.
Definition adapter_i2c.cpp:1087
bool restorePins()
Reattach SDA/SCL to the I2C controller as they were before releasePins()
Definition adapter_i2c.cpp:1130
ImplType implType() const
Gets the I2C implementation type.
Definition adapter_i2c.hpp:447
int16_t port() const
I2C port number, or -1 if unknown (TwoWire, Bus, or a bus handle added without its port)
Definition adapter_i2c.hpp:453
Top level namespace of M5Stack.
Definition test_helper.hpp:20
PIN settings save/restore.