Skip to content

Commit b8d5fe1

Browse files
committed
Merge branch 'feature/esp-idf-native-support' into develop
2 parents a302fd6 + 91558a7 commit b8d5fe1

21 files changed

Lines changed: 1568 additions & 56 deletions

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,10 @@ tmp/
5454
*.pem
5555
*.key
5656
*.cert
57+
58+
# ESP-IDF artifacts (local idf.py runs)
59+
managed_components/
60+
build/
61+
dependencies.lock
62+
sdkconfig
63+
sdkconfig.old

CMakeLists.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# ESP-IDF component manifest for M5UnitUnified.
2+
# Upstream: https://github.com/m5stack/M5UnitUnified
3+
#
4+
# Notes
5+
# - All Arduino-specific code paths (TwoWire / HardwareSerial / Wire.h /
6+
# HardwareSerial.h) are guarded with `#if defined(ARDUINO)` upstream, so
7+
# under pure ESP-IDF those branches are skipped. The ESPIDFMasterBus path
8+
# (i2c_master_bus_handle_t) is the one used in non-Arduino builds.
9+
# - googletest helpers (src/googletest/*) are EXCLUDED — they pull in
10+
# <M5Unified.h> for test scaffolding only and are not needed at runtime.
11+
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
12+
13+
file(GLOB_RECURSE SRCS "src/*.cpp")
14+
list(FILTER SRCS EXCLUDE REGEX "/googletest/")
15+
16+
set(public_requires driver M5HAL)
17+
set(private_requires esp_adc esp_timer M5Utility)
18+
19+
# Keep IDF 5.x on the driver meta-component. IDF v6 no longer exposes all split
20+
# driver include paths transitively, so add only the v6-specific component deps.
21+
if("${IDF_VERSION_MAJOR}" VERSION_GREATER_EQUAL "6")
22+
list(APPEND public_requires esp_driver_gpio esp_driver_i2c esp_driver_rmt esp_driver_spi esp_driver_uart esp_hw_support)
23+
list(APPEND private_requires esp_driver_ledc esp_ringbuf)
24+
endif()
25+
26+
idf_component_register(
27+
SRCS ${SRCS}
28+
INCLUDE_DIRS "src"
29+
REQUIRES ${public_requires}
30+
PRIV_REQUIRES ${private_requires}
31+
)
32+
33+
# Optionally link M5Unified only when it is already part of the build (e.g. a M5Unified-based
34+
# app or example). This puts M5GFX's <utility/I2C_Class.hpp> on adapter_i2c.cpp's include path,
35+
# so the real m5::I2C_Class adapter is compiled instead of the stub. Pure ESP-IDF builds without
36+
# M5Unified are unaffected (the component is simply skipped). Available since IDF v5.0.
37+
# Both names are listed: m5stack__M5Unified (registry/git) and M5Unified (local components/).
38+
idf_component_optional_requires(PRIVATE m5stack__M5Unified M5Unified)

README.ja.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,8 @@ void loop() {
284284

285285
## サポートされているもの
286286
### サポートされるフレームワーク
287-
- Arduino
287+
- Arduino (Arduino-ESP32)
288+
- ESP-IDF (>=5.0)
288289

289290
将来的には Wire クラス等を直接使わず、全て M5HAL 経由で接続を行えるようになる予定です。
290291

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ void loop() {
285285

286286
## Supported things
287287
### Supported frameworks
288-
- Arduino
288+
- Arduino (Arduino-ESP32)
289+
- ESP-IDF (>=5.0)
289290

290291
In the future, all connections will be made through M5HAL, eliminating the need to use Wire class etc. directly.
291292

idf_component.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
description: Unified library for handling various M5 unit products (sensors, actuators, peripherals).
2+
url: https://github.com/m5stack/M5UnitUnified
3+
issues: https://github.com/m5stack/M5UnitUnified/issues
4+
license: MIT
5+
version: "0.4.6"
6+
7+
dependencies:
8+
idf: ">=5.0"
9+
m5stack/M5HAL:
10+
git: https://github.com/m5stack/M5HAL.git
11+
version: main
12+
m5stack/M5Utility:
13+
git: https://github.com/m5stack/M5Utility.git
14+
version: main
15+
16+
targets:
17+
- esp32
18+
- esp32s3
19+
- esp32c3
20+
- esp32c6
21+
- esp32p4
22+
- esp32h2
23+
24+
files:
25+
exclude:
26+
- "docs/**"
27+
- "test/**"
28+
- ".github/**"
29+
- "boards/**"
30+
- "src/googletest/**"
31+
- "platformio.ini"
32+
- "library.json"
33+
- "library.properties"

library.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
"url": "https://github.com/m5stack/M5UnitUnified.git"
1212
},
1313
"dependencies": {
14-
"m5stack/M5Utility": ">=0.0.13",
15-
"m5stack/M5HAL": ">=0.0.4"
14+
"m5stack/M5Utility": ">=0.1.0",
15+
"m5stack/M5HAL": ">=0.1.0"
1616
},
1717
"version": "0.4.8",
1818
"frameworks": [
19-
"arduino"
19+
"arduino",
20+
"espidf"
2021
],
2122
"platforms": [
2223
"espressif32"

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ version=0.4.8
33
author=M5Stack
44
maintainer=M5Stack
55
sentence=M5UnitUnified is a library for unified handling of various M5 units products.
6-
paragraph=
6+
paragraph=Unified hardware abstraction for M5Stack units with common APIs for I2C, GPIO, UART, and SPI communications.
77
category=Device Control
88
url=https://github.com/m5stack/M5UnitUnified
99
architectures=esp32
1010
includes=M5UnitUnified.h
11-
depends=M5Utility (>=0.0.13),M5HAL (>=0.0.4)
11+
depends=M5Utility,M5HAL

src/M5UnitComponent.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ bool Component::assign(m5::hal::bus::Bus* bus)
166166
}
167167
}
168168

169+
#if defined(ARDUINO)
169170
bool Component::assign(TwoWire& wire)
170171
{
171172
if (canAccessI2C() && _addr) {
@@ -174,6 +175,7 @@ bool Component::assign(TwoWire& wire)
174175
}
175176
return false;
176177
}
178+
#endif
177179

178180
bool Component::assign(m5::I2C_Class& i2c)
179181
{
@@ -184,6 +186,26 @@ bool Component::assign(m5::I2C_Class& i2c)
184186
return false;
185187
}
186188

189+
#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
190+
bool Component::assign(i2c_master_bus_handle_t bus)
191+
{
192+
if (canAccessI2C() && _addr && bus) {
193+
_adapter = std::make_shared<AdapterI2C>(bus, _addr, _component_cfg.clock);
194+
return static_cast<bool>(_adapter);
195+
}
196+
return false;
197+
}
198+
#elif defined(ESP_PLATFORM)
199+
bool Component::assign(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl)
200+
{
201+
if (canAccessI2C() && _addr) {
202+
_adapter = std::make_shared<AdapterI2C>(port, sda, scl, _addr, _component_cfg.clock);
203+
return static_cast<bool>(_adapter);
204+
}
205+
return false;
206+
}
207+
#endif
208+
187209
bool Component::assign(const int8_t rx_pin, const int8_t tx_pin)
188210
{
189211
if (canAccessGPIO()) {
@@ -193,6 +215,7 @@ bool Component::assign(const int8_t rx_pin, const int8_t tx_pin)
193215
return false;
194216
}
195217

218+
#if defined(ARDUINO)
196219
bool Component::assign(HardwareSerial& serial)
197220
{
198221
if (canAccessUART()) {
@@ -205,11 +228,35 @@ bool Component::assign(HardwareSerial& serial)
205228
bool Component::assign(SPIClass& spi, const SPISettings& settings)
206229
{
207230
if (canAccessSPI()) {
208-
_adapter = std::make_shared<AdapterSPI>(spi, settings, address() /* CS */);
231+
// address() is reused as the CS GPIO number on SPI units (see CapST25R3916 etc.)
232+
_adapter = std::make_shared<AdapterSPI>(spi, settings, static_cast<gpio_num_t>(address()) /* CS */);
233+
return static_cast<bool>(_adapter);
234+
}
235+
return false;
236+
}
237+
#endif
238+
239+
#if defined(ESP_PLATFORM)
240+
bool Component::assign(const uart_port_t uart_num)
241+
{
242+
if (canAccessUART() && uart_is_driver_installed(uart_num)) {
243+
_adapter = std::make_shared<AdapterUART>(uart_num);
244+
return static_cast<bool>(_adapter);
245+
}
246+
return false;
247+
}
248+
249+
bool Component::assign(spi_device_handle_t handle, const gpio_num_t cs)
250+
{
251+
if (canAccessSPI()) {
252+
// If cs is omitted (GPIO_NUM_NC), use address() as the CS pin (same convention as Arduino SPI).
253+
const gpio_num_t actual_cs = (cs == GPIO_NUM_NC) ? static_cast<gpio_num_t>(address()) : cs;
254+
_adapter = std::make_shared<AdapterSPI>(handle, actual_cs);
209255
return static_cast<bool>(_adapter);
210256
}
211257
return false;
212258
}
259+
#endif
213260

214261
bool Component::selectChannel(const uint8_t ch)
215262
{

src/M5UnitComponent.hpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,28 @@
1212

1313
#include "m5_unit_component/types.hpp"
1414
#include "m5_unit_component/adapter.hpp"
15+
#if defined(ESP_PLATFORM)
16+
#include <driver/uart.h> // for uart_port_t
17+
#include <driver/spi_master.h> // for spi_device_handle_t
18+
#endif
19+
#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
20+
#include <driver/i2c_master.h> // for i2c_master_bus_handle_t
21+
#elif defined(ESP_PLATFORM)
22+
#include <driver/i2c.h> // for i2c_port_t / gpio_num_t
23+
#endif
1524
#include <cstdint>
1625
#include <vector>
1726
#include <algorithm>
1827
#include <iterator>
1928
#include <type_traits>
2029
#include <memory>
2130

31+
#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
2232
class TwoWire;
2333
class HardwareSerial;
2434
class SPIClass;
2535
struct SPISettings;
36+
#endif
2637

2738
namespace m5 {
2839
class I2C_Class;
@@ -287,12 +298,32 @@ class Component {
287298

288299
///@name Assign(I2C)
289300
///@{
301+
#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
290302
/*!
291303
@brief Assign TwoWire as the communication bus
292304
@param wire TwoWire to be used
293305
@return True if successful
294306
*/
295307
virtual bool assign(TwoWire& wire);
308+
#endif
309+
#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>))
310+
/*!
311+
@brief Assign I2C master bus (ESP-IDF native driver)
312+
@param bus ESP-IDF I2C master bus handle
313+
@return True if successful
314+
*/
315+
virtual bool assign(i2c_master_bus_handle_t bus);
316+
#endif
317+
#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && !__has_include(<driver/i2c_master.h>))
318+
/*!
319+
@brief Assign I2C (ESP-IDF legacy driver, pre-installed port)
320+
@param port I2C port (the driver must be installed beforehand via i2c_param_config / i2c_driver_install)
321+
@param sda SDA GPIO
322+
@param scl SCL GPIO
323+
@return True if successful
324+
*/
325+
virtual bool assign(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl);
326+
#endif
296327
/*!
297328
@brief Assign I2C_Class as the communication bus
298329
@param i2c I2C_Class to be used (e.g. M5.In_I2C)
@@ -314,23 +345,46 @@ class Component {
314345

315346
///@name Assign(UART)
316347
///@{
348+
#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
317349
/*!
318350
@brief Assign HardwareSerial as the communication bus
319351
@param serial HardwareSerial to be used
320352
@return True if successful
321353
*/
322354
virtual bool assign(HardwareSerial& serial);
355+
#endif
356+
#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
357+
/*!
358+
@brief Assign UART (ESP-IDF native driver, pre-installed port)
359+
@param uart_num UART port number (the driver must be installed beforehand via
360+
uart_driver_install / uart_param_config / uart_set_pin)
361+
@return True if successful
362+
*/
363+
virtual bool assign(const uart_port_t uart_num);
364+
#endif
323365
///@}
324366

325367
///@name Assign(SPI)
326368
///@{
369+
#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
327370
/*!
328371
@brief Assign SPIClass as the communication bus
329372
@param spi SPIClass to be used
330373
@param settings SPI settings to be applied
331374
@return True if successful
332375
*/
333376
virtual bool assign(SPIClass& spi, const SPISettings& settings);
377+
#endif
378+
#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
379+
/*!
380+
@brief Assign SPI device handle (ESP-IDF native driver, borrowed)
381+
@param handle ESP-IDF SPI device handle (create with spics_io_num = -1; init bus with SPI_DMA_DISABLED)
382+
@param cs CS GPIO controlled manually by this library. If `GPIO_NUM_NC` (default), uses `address()` as the CS pin
383+
(same convention as Arduino SPI)
384+
@return True if successful
385+
*/
386+
virtual bool assign(spi_device_handle_t handle, const gpio_num_t cs = GPIO_NUM_NC);
387+
#endif
334388
///@}
335389

336390
///@name Assign(M5HAL)

0 commit comments

Comments
 (0)