1717#include < soc/gpio_struct.h>
1818#include < soc/gpio_sig_map.h>
1919#include < cassert>
20+ #if __has_include(<utility/I2C_Class.hpp>)
21+ #include < utility/I2C_Class.hpp>
22+ #define M5_UNITUNIFIED_ADAPTER_HAS_M5_I2C_CLASS
23+ #endif
2024
2125#if defined(ARDUINO)
2226
@@ -325,6 +329,193 @@ m5::hal::error::error_t AdapterI2C::BusImpl::write_with_transaction(const m5::ha
325329 return m5::hal::error::error_t ::INVALID_ARGUMENT;
326330}
327331
332+ // Impl for I2C_Class
333+ #if defined(M5_UNITUNIFIED_ADAPTER_HAS_M5_I2C_CLASS)
334+
335+ AdapterI2C::I2CClassImpl::I2CClassImpl (m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock)
336+ : AdapterI2C::I2CImpl(addr, clock), _i2c(&i2c)
337+ {
338+ _sda = _i2c->getSDA ();
339+ _scl = _i2c->getSCL ();
340+ M5_LIB_LOGI (" I2C_Class SDA:%d, SCL:%d" , _sda, _scl);
341+ }
342+
343+ bool AdapterI2C::I2CClassImpl::begin ()
344+ {
345+ return true ; // Already initialized by M5Unified
346+ }
347+
348+ bool AdapterI2C::I2CClassImpl::end ()
349+ {
350+ return true ; // Managed by M5Unified
351+ }
352+
353+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::readWithTransaction (uint8_t * data, const size_t len)
354+ {
355+ assert (_addr);
356+ if (!data) {
357+ return m5::hal::error::error_t ::INVALID_ARGUMENT;
358+ }
359+ bool started = _in_transaction ? _i2c->restart (_addr, true , _clock) : _i2c->start (_addr, true , _clock);
360+ if (!started) {
361+ _in_transaction = false ;
362+ return m5::hal::error::error_t ::I2C_BUS_ERROR;
363+ }
364+ bool ok = _i2c->read (data, len, true );
365+ _i2c->stop ();
366+ _in_transaction = false ;
367+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
368+ }
369+
370+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint8_t * data, const size_t len,
371+ const uint32_t stop)
372+ {
373+ assert (_addr);
374+ bool started = _in_transaction ? _i2c->restart (_addr, false , _clock) : _i2c->start (_addr, false , _clock);
375+ if (!started) {
376+ _in_transaction = false ;
377+ return m5::hal::error::error_t ::I2C_BUS_ERROR;
378+ }
379+ bool ok = true ;
380+ if (data && len) {
381+ ok = _i2c->write (data, len);
382+ }
383+ if (stop || !ok) {
384+ _i2c->stop ();
385+ _in_transaction = false ;
386+ } else {
387+ _in_transaction = true ;
388+ }
389+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
390+ }
391+
392+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint8_t reg, const uint8_t * data,
393+ const size_t len, const uint32_t stop)
394+ {
395+ assert (_addr);
396+ bool started = _in_transaction ? _i2c->restart (_addr, false , _clock) : _i2c->start (_addr, false , _clock);
397+ if (!started) {
398+ _in_transaction = false ;
399+ return m5::hal::error::error_t ::I2C_BUS_ERROR;
400+ }
401+ bool ok = _i2c->write (reg);
402+ if (ok && data && len) {
403+ ok = _i2c->write (data, len);
404+ }
405+ if (stop || !ok) {
406+ _i2c->stop ();
407+ _in_transaction = false ;
408+ } else {
409+ _in_transaction = true ;
410+ }
411+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
412+ }
413+
414+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint16_t reg, const uint8_t * data,
415+ const size_t len, const uint32_t stop)
416+ {
417+ assert (_addr);
418+ m5::types::big_uint16_t r (reg);
419+ bool started = _in_transaction ? _i2c->restart (_addr, false , _clock) : _i2c->start (_addr, false , _clock);
420+ if (!started) {
421+ _in_transaction = false ;
422+ return m5::hal::error::error_t ::I2C_BUS_ERROR;
423+ }
424+ bool ok = _i2c->write (r.data (), r.size ());
425+ if (ok && data && len) {
426+ ok = _i2c->write (data, len);
427+ }
428+ if (stop || !ok) {
429+ _i2c->stop ();
430+ _in_transaction = false ;
431+ } else {
432+ _in_transaction = true ;
433+ }
434+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
435+ }
436+
437+ AdapterI2C::I2CImpl* AdapterI2C::I2CClassImpl::duplicate (const uint8_t addr)
438+ {
439+ return new I2CClassImpl (*_i2c, addr, _clock);
440+ }
441+
442+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::generalCall (const uint8_t * data, const size_t len)
443+ {
444+ bool ok = _i2c->start (0x00 , false , _clock);
445+ if (ok && data && len) {
446+ ok = _i2c->write (data, len);
447+ }
448+ _i2c->stop ();
449+ _in_transaction = false ;
450+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
451+ }
452+
453+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::wakeup ()
454+ {
455+ bool ok = _i2c->start (_addr, false , _clock);
456+ _i2c->stop ();
457+ _in_transaction = false ;
458+ return ok ? m5::hal::error::error_t ::OK : m5::hal::error::error_t ::I2C_BUS_ERROR;
459+ }
460+
461+ #else
462+ // Stub when I2C_Class is not available
463+ AdapterI2C::I2CClassImpl::I2CClassImpl (m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock)
464+ : AdapterI2C::I2CImpl(addr, clock)
465+ {
466+ (void )i2c;
467+ M5_LIB_LOGE (" I2C_Class not available" );
468+ }
469+
470+ bool AdapterI2C::I2CClassImpl::begin ()
471+ {
472+ return false ;
473+ }
474+
475+ bool AdapterI2C::I2CClassImpl::end ()
476+ {
477+ return false ;
478+ }
479+
480+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::readWithTransaction (uint8_t *, const size_t )
481+ {
482+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
483+ }
484+
485+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint8_t *, const size_t , const uint32_t )
486+ {
487+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
488+ }
489+
490+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint8_t , const uint8_t *, const size_t ,
491+ const uint32_t )
492+ {
493+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
494+ }
495+
496+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::writeWithTransaction (const uint16_t , const uint8_t *, const size_t ,
497+ const uint32_t )
498+ {
499+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
500+ }
501+
502+ AdapterI2C::I2CImpl* AdapterI2C::I2CClassImpl::duplicate (const uint8_t addr)
503+ {
504+ return new I2CImpl (addr, _clock);
505+ }
506+
507+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::generalCall (const uint8_t *, const size_t )
508+ {
509+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
510+ }
511+
512+ m5::hal::error::error_t AdapterI2C::I2CClassImpl::wakeup ()
513+ {
514+ return m5::hal::error::error_t ::UNKNOWN_ERROR;
515+ }
516+
517+ #endif
518+
328519// Adapter
329520#if defined(ARDUINO)
330521AdapterI2C::AdapterI2C (TwoWire& wire, const uint8_t addr, const uint32_t clock)
@@ -351,6 +542,24 @@ AdapterI2C::AdapterI2C(m5::hal::bus::Bus* bus, const uint8_t addr, const uint32_
351542 assert (_impl);
352543}
353544
545+ #if defined(M5_UNITUNIFIED_ADAPTER_HAS_M5_I2C_CLASS)
546+ AdapterI2C::AdapterI2C (m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock)
547+ : Adapter(Adapter::Type::I2C, new AdapterI2C::I2CClassImpl(i2c, addr, clock))
548+ {
549+ assert (_impl);
550+ }
551+ #else
552+ #pragma message "Not support I2C_Class"
553+ AdapterI2C::AdapterI2C (m5::I2C_Class& i2c, const uint8_t addr, const uint32_t clock) : Adapter()
554+ {
555+ (void )i2c;
556+ (void )addr;
557+ (void )clock;
558+ assert (_impl);
559+ M5_LIB_LOGE (" Not support I2C_Class" );
560+ }
561+ #endif
562+
354563Adapter* AdapterI2C::duplicate (const uint8_t addr)
355564{
356565 auto ptr = new AdapterI2C ();
0 commit comments