Skip to content

Commit 2990d3c

Browse files
committed
Merge branch 'develop'
2 parents 8caae3d + a40dc9b commit 2990d3c

4 files changed

Lines changed: 59 additions & 3 deletions

File tree

idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ description: Unified library for handling various M5 unit products (sensors, act
22
url: https://github.com/m5stack/M5UnitUnified
33
issues: https://github.com/m5stack/M5UnitUnified/issues
44
license: MIT
5-
version: "0.5.1"
5+
version: "0.5.2"
66

77
dependencies:
88
idf: ">=5.0"

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"m5stack/M5Utility": ">=0.1.0",
1515
"m5stack/M5HAL": ">=0.1.0"
1616
},
17-
"version": "0.5.1",
17+
"version": "0.5.2",
1818
"frameworks": [
1919
"arduino",
2020
"espidf"

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=M5UnitUnified
2-
version=0.5.1
2+
version=0.5.2
33
author=M5Stack
44
maintainer=M5Stack
55
sentence=M5UnitUnified is a library for unified handling of various M5 units products.

src/wiring/m5_unit_unified_wiring.hpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@
3838
#include <SPI.h>
3939
#include <HardwareSerial.h>
4040
#else // ESP-IDF native
41+
// driver/i2c_master.h (new I2C master driver) exists only on IDF >= 5.2. On IDF 5.0/5.1 fall back to
42+
// the legacy driver/i2c.h so the I2C wiring helpers keep working across the whole IDF >= 5.0 range.
43+
#if __has_include(<driver/i2c_master.h>)
4144
#include <driver/i2c_master.h>
45+
#else
46+
#include <driver/i2c.h>
47+
#endif
4248
#include <driver/uart.h>
4349
#include <driver/spi_master.h>
4450
#include <hal/gpio_types.h>
@@ -571,10 +577,12 @@ constexpr size_t kUARTPortCacheSize = 4;
571577
constexpr size_t kSPIHostCacheSize = 2; // SPI2_HOST / SPI3_HOST
572578
constexpr size_t kSPIDevCacheSize = 4;
573579

580+
#if __has_include(<driver/i2c_master.h>)
574581
struct I2CCacheEntry {
575582
uint32_t key;
576583
i2c_master_bus_handle_t handle;
577584
};
585+
#endif
578586

579587
struct UARTCacheEntry {
580588
uint32_t key;
@@ -591,6 +599,7 @@ struct SPIDevEntry {
591599
spi_device_handle_t handle;
592600
};
593601

602+
#if __has_include(<driver/i2c_master.h>)
594603
//! @brief Get or create an I2C master bus, cached by {port, sda, scl}.
595604
inline i2c_master_bus_handle_t ensureI2CBus(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl,
596605
const uint32_t /*clock - not used to key, single bus per pins*/)
@@ -629,6 +638,38 @@ inline i2c_master_bus_handle_t ensureI2CBus(const i2c_port_t port, const gpio_nu
629638
cache[count].key = key;
630639
return cache[count++].handle;
631640
}
641+
#else // legacy driver/i2c.h (IDF 5.0 / 5.1)
642+
//! @brief Install the legacy I2C master driver once per {port, sda, scl}; cached so re-adds are no-ops.
643+
inline bool ensureI2CLegacyDriver(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl,
644+
const uint32_t clock)
645+
{
646+
const uint32_t key = (static_cast<uint32_t>(static_cast<uint8_t>(port)) << 24) |
647+
(static_cast<uint32_t>(static_cast<uint8_t>(sda)) << 16) |
648+
(static_cast<uint32_t>(static_cast<uint8_t>(scl)) << 8);
649+
static uint32_t cache[kI2CBusCacheSize]{};
650+
static size_t count{};
651+
for (size_t i = 0; i < count; ++i) {
652+
if (cache[i] == key) return true;
653+
}
654+
if (count >= kI2CBusCacheSize) {
655+
M5_LIB_LOGE("wiring: I2C bus cache full (max %zu)", kI2CBusCacheSize);
656+
return false;
657+
}
658+
i2c_config_t conf{};
659+
conf.mode = I2C_MODE_MASTER;
660+
conf.sda_io_num = sda;
661+
conf.scl_io_num = scl;
662+
conf.sda_pullup_en = true;
663+
conf.scl_pullup_en = true;
664+
conf.master.clk_speed = clock;
665+
if (i2c_param_config(port, &conf) != ESP_OK || i2c_driver_install(port, I2C_MODE_MASTER, 0, 0, 0) != ESP_OK) {
666+
M5_LIB_LOGE("wiring: legacy i2c driver install failed port=%d sda=%d scl=%d", (int)port, (int)sda, (int)scl);
667+
return false;
668+
}
669+
cache[count++] = key;
670+
return true;
671+
}
672+
#endif
632673

633674
//! @brief Get or install a UART port, cached by {port, rx, tx}.
634675
inline uart_port_t ensureUARTPort(const uart_port_t port, const gpio_num_t rx, const gpio_num_t tx, const uint32_t baud,
@@ -727,15 +768,18 @@ inline spi_device_handle_t ensureSPIDevice(const spi_host_device_t host, const g
727768

728769
} // namespace detail
729770

771+
#if __has_include(<driver/i2c_master.h>)
730772
/*!
731773
@brief Get or create an I2C master bus handle (cached by {port, sda, scl})
732774
@note Intended for unit-specific wiring in M5Unit-* libraries; examples should use addI2C() instead.
775+
@note Available only on IDF >= 5.2 (new I2C master driver). On IDF 5.0/5.1 use addI2C() instead.
733776
*/
734777
inline i2c_master_bus_handle_t i2cBusHandle(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl,
735778
const uint32_t clock = 100000)
736779
{
737780
return detail::ensureI2CBus(port, sda, scl, clock);
738781
}
782+
#endif
739783

740784
/*!
741785
@brief Get or install a UART port (cached by {port, rx, tx})
@@ -793,9 +837,16 @@ inline bool addI2C(UnitUnified& units, Component& unit, const uint32_t clock = 1
793837
return i2cClass(units, unit, M5.In_I2C);
794838
} else {
795839
// Core / Stick / S3 etc: M5Unified does not call Wire.begin(), so install ourselves
840+
#if __has_include(<driver/i2c_master.h>)
796841
auto bus = i2cBusHandle(I2C_NUM_0, (gpio_num_t)pins.sda, (gpio_num_t)pins.scl, clock);
797842
if (!bus) return false;
798843
return units.add(unit, bus);
844+
#else // legacy driver (IDF 5.0 / 5.1): install legacy driver, then add by port
845+
if (!detail::ensureI2CLegacyDriver(I2C_NUM_0, (gpio_num_t)pins.sda, (gpio_num_t)pins.scl, clock)) {
846+
return false;
847+
}
848+
return units.add(unit, I2C_NUM_0, (gpio_num_t)pins.sda, (gpio_num_t)pins.scl);
849+
#endif
799850
}
800851
case I2CPins::Backend::ExI2C:
801852
// NanoC6 / NanoH2: M5Unified manages Ex_I2C -> borrow
@@ -863,9 +914,14 @@ inline bool addHatI2C(UnitUnified& units, Component& unit, const uint32_t clock
863914
}
864915
M5_LIB_LOGI("wiring(ESP-IDF): addHatI2C port=%d sda=%d scl=%d clock=%u", (int)port, (int)p.sda, (int)p.scl,
865916
(unsigned)clock);
917+
#if __has_include(<driver/i2c_master.h>)
866918
auto bus = i2cBusHandle(port, (gpio_num_t)p.sda, (gpio_num_t)p.scl, clock);
867919
if (!bus) return false;
868920
return units.add(unit, bus);
921+
#else // legacy driver (IDF 5.0 / 5.1)
922+
if (!detail::ensureI2CLegacyDriver(port, (gpio_num_t)p.sda, (gpio_num_t)p.scl, clock)) return false;
923+
return units.add(unit, port, (gpio_num_t)p.sda, (gpio_num_t)p.scl);
924+
#endif
869925
}
870926

871927
//! @brief Add a unit on the board's Hat GPIO header (ESP-IDF native)

0 commit comments

Comments
 (0)