From 2c2c11ff2884b54cf3b8b76695564e9c3e3afa48 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:44:37 +0200 Subject: [PATCH 001/175] IDF 5.3 support --- builder/frameworks/espidf.py | 111 ++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 08c14bb..656c853 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -67,7 +67,9 @@ IDF5 = ( IDF_ENV_VERSION = "1.0.0" FRAMEWORK_DIR = platform.get_package_dir("framework-espidf") TOOLCHAIN_DIR = platform.get_package_dir( - "toolchain-%s" % ("riscv32-esp" if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2") else ("xtensa-%s" % mcu)) + "toolchain-riscv32-esp" + if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4") + else "toolchain-xtensa-esp-elf" ) @@ -248,7 +250,7 @@ def populate_idf_env_vars(idf_env): os.path.dirname(get_python_exe()), ] - if mcu not in ("esp32c2", "esp32c3", "esp32c6","esp32h2"): + if mcu not in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): additional_packages.append( os.path.join(platform.get_package_dir("toolchain-esp32ulp"), "bin"), ) @@ -503,7 +505,7 @@ def extract_linker_script_fragments_backup(framework_components_dir, sdk_config) sys.stderr.write("Error: Failed to extract paths to linker script fragments\n") env.Exit(1) - if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2"): + if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): result.append(os.path.join(framework_components_dir, "riscv", "linker.lf")) # Add extra linker fragments @@ -644,16 +646,30 @@ def generate_project_ld_script(sdk_config, ignore_targets=None): '--objdump "{objdump}"' ).format(**args) + initial_ld_script = os.path.join( + FRAMEWORK_DIR, + "components", + "esp_system", + "ld", + idf_variant, + "sections.ld.in", + ) + + if IDF5: + initial_ld_script = preprocess_linker_file( + initial_ld_script, + os.path.join( + BUILD_DIR, + "esp-idf", + "esp_system", + "ld", + "sections.ld.in", + ) + ) + return env.Command( os.path.join("$BUILD_DIR", "sections.ld"), - os.path.join( - FRAMEWORK_DIR, - "components", - "esp_system", - "ld", - idf_variant, - "sections.ld.in", - ), + initial_ld_script, env.VerboseAction(cmd, "Generating project linker script $TARGET"), ) @@ -1103,6 +1119,46 @@ def get_app_partition_offset(pt_table, pt_offset): return app_params.get("offset", "0x10000") +def preprocess_linker_file(src_ld_script, target_ld_script): + return env.Command( + target_ld_script, + src_ld_script, + env.VerboseAction( + " ".join( + [ + os.path.join( + platform.get_package_dir("tool-cmake"), + "bin", + "cmake", + ), + "-DCC=%s" + % os.path.join( + TOOLCHAIN_DIR, + "bin", + "$CC", + ), + "-DSOURCE=$SOURCE", + "-DTARGET=$TARGET", + "-DCONFIG_DIR=%s" % os.path.join(BUILD_DIR, "config"), + "-DLD_DIR=%s" + % os.path.join( + FRAMEWORK_DIR, "components", "esp_system", "ld" + ), + "-P", + os.path.join( + "$BUILD_DIR", + "esp-idf", + "esp_system", + "ld", + "linker_script_generator.cmake", + ), + ] + ), + "Generating LD script $TARGET", + ), + ) + + def generate_mbedtls_bundle(sdk_config): bundle_path = os.path.join("$BUILD_DIR", "x509_crt_bundle") if os.path.isfile(env.subst(bundle_path)): @@ -1349,19 +1405,30 @@ generate_default_component() # if not board.get("build.ldscript", ""): - linker_script = env.Command( - os.path.join("$BUILD_DIR", "memory.ld"), - board.get( - "build.esp-idf.ldscript", + initial_ld_script = board.get("build.esp-idf.ldscript", os.path.join( + FRAMEWORK_DIR, + "components", + "esp_system", + "ld", + idf_variant, + "memory.ld.in", + )) + + if IDF5: + initial_ld_script = preprocess_linker_file( + initial_ld_script, os.path.join( - FRAMEWORK_DIR, - "components", + BUILD_DIR, + "esp-idf", "esp_system", "ld", - idf_variant, "memory.ld.in", - ), - ), + ) + ) + + linker_script = env.Command( + os.path.join("$BUILD_DIR", "memory.ld"), + initial_ld_script, env.VerboseAction( '$CC -I"$BUILD_DIR/config" -I"%s" -C -P -x c -E $SOURCE -o $TARGET' % os.path.join(FRAMEWORK_DIR, "components", "esp_system", "ld"), @@ -1601,7 +1668,7 @@ env.Prepend( ( board.get( "upload.bootloader_offset", - "0x0" if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32s3", "esp32h2") else "0x1000", + "0x0" if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32s3", "esp32h2") else ("0x2000" if mcu in ("esp32p4") else "0x1000"), ), os.path.join("$BUILD_DIR", "bootloader.bin"), ), @@ -1712,7 +1779,7 @@ env["BUILDERS"]["ElfToBin"].action = action # ulp_dir = os.path.join(PROJECT_DIR, "ulp") -if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32h2"): +if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): env.SConscript("ulp.py", exports="env sdk_config project_config idf_variant") # From 050e8176c5d832bd0fbaf1976e5e7b1fdfd6fcbb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:04:15 +0200 Subject: [PATCH 002/175] IDF 5.3 --- platform.json | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/platform.json b/platform.json index ffc9bab..ef6d7eb 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "51.03.03+develop", + "version": "53.03.03+develop", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -45,37 +45,25 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.1.4.240726/esp-idf-v5.1.4.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.0/esp-idf-v5.3.0.zip" }, - "toolchain-xtensa-esp32": { + "toolchain-xtensa-esp-elf": { "type": "toolchain", "optional": true, "owner": "espressif", - "version": "12.2.0+20230208" - }, - "toolchain-xtensa-esp32s2": { - "type": "toolchain", - "optional": true, - "owner": "espressif", - "version": "12.2.0+20230208" - }, - "toolchain-xtensa-esp32s3": { - "type": "toolchain", - "optional": true, - "owner": "espressif", - "version": "12.2.0+20230208" + "version": "13.2.0+20240530" }, "toolchain-riscv32-esp": { "type": "toolchain", "optional": true, "owner": "espressif", - "version": "12.2.0+20230208" + "version": "13.2.0+20240530" }, "toolchain-esp32ulp": { "type": "toolchain", "optional": true, "owner": "platformio", - "version": "~1.23500.0" + "version": "~1.23800.0" }, "tool-xtensa-esp-elf-gdb": { "type": "debugger", From 273fa1277e8b13dee06905d915d10ca19d450eed Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:24:08 +0200 Subject: [PATCH 003/175] IDF 5.3 toolchains remove dynamic toolchains support, currently only older incompatible are possible to fetch. --- platform.py | 164 ++-------------------------------------------------- 1 file changed, 6 insertions(+), 158 deletions(-) diff --git a/platform.py b/platform.py index 0debfbd..03b118d 100644 --- a/platform.py +++ b/platform.py @@ -63,46 +63,6 @@ class Espressif32Platform(PlatformBase): else: del self.packages["tool-dfuutil-arduino"] - build_core = variables.get( - "board_build.core", board_config.get("build.core", "arduino") - ).lower() - - if frameworks == ["arduino"] and build_core == "esp32": - # In case the upstream Arduino framework is specified in the configuration - # file then we need to dynamically extract toolchain versions from the - # Arduino index file. This feature can be disabled via a special option: - if ( - variables.get( - "board_build.arduino.upstream_packages", - board_config.get("build.arduino.upstream_packages", "no"), - ).lower() - == "yes" - ): - package_version = self.packages["framework-arduinoespressif32"][ - "version" - ] - - url_items = urllib.parse.urlparse(package_version) - # Only GitHub repositories support dynamic packages - if ( - url_items.scheme in ("http", "https") - and url_items.netloc.startswith("github") - and url_items.path.endswith(".git") - ): - try: - self.configure_upstream_arduino_packages(url_items) - except Exception as e: - sys.stderr.write( - "Error! Failed to extract upstream toolchain" - "configurations:\n%s\n" % str(e) - ) - sys.stderr.write( - "You can disable this feature via the " - "`board_build.arduino.upstream_packages = no` setting in " - "your `platformio.ini` file.\n" - ) - sys.exit(1) - # Starting from v12, Espressif's toolchains are shipped without # bundled GDB. Instead, it's distributed as separate packages for Xtensa # and RISC-V targets. @@ -122,14 +82,13 @@ class Espressif32Platform(PlatformBase): # elif p in ("tool-mconf", "tool-idf") and IS_WINDOWS: # self.packages[p]["optional"] = False - for available_mcu in ("esp32", "esp32s2", "esp32s3"): - if available_mcu == mcu: - self.packages["toolchain-xtensa-%s" % mcu]["optional"] = False - else: - self.packages.pop("toolchain-xtensa-%s" % available_mcu, None) + if mcu in ("esp32", "esp32s2", "esp32s3"): + self.packages["toolchain-xtensa-esp-elf"]["optional"] = False + else: + self.packages.pop("toolchain-xtensa-esp-elf", None) - if mcu in ("esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2"): - if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2"): + if mcu in ("esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): + if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): self.packages.pop("toolchain-esp32ulp", None) # RISC-V based toolchain for ESP32C3, ESP32C6 ESP32S2, ESP32S3 ULP self.packages["toolchain-riscv32-esp"]["optional"] = False @@ -282,114 +241,3 @@ class Espressif32Platform(PlatformBase): ) ) debug_config.load_cmds = load_cmds - - - @staticmethod - def extract_toolchain_versions(tool_deps): - def _parse_version(original_version): - assert original_version - version_patterns = ( - r"^gcc(?P\d+)_(?P\d+)_(?P\d+)-esp-(?P.+)$", - r"^esp-(?P.+)-(?P\d+)\.(?P\d+)\.?(?P\d+)$", - r"^esp-(?P\d+)\.(?P\d+)\.(?P\d+)(_(?P.+))?$", - ) - for pattern in version_patterns: - match = re.search(pattern, original_version) - if match: - result = "%s.%s.%s" % ( - match.group("MAJOR"), - match.group("MINOR"), - match.group("PATCH"), - ) - if match.group("EXTRA"): - result = result + "+%s" % match.group("EXTRA") - return result - - raise ValueError("Bad package version `%s`" % original_version) - - if not tool_deps: - raise ValueError( - ("Failed to extract tool dependencies from the remote package file") - ) - - toolchain_remap = { - "xtensa-esp32-elf-gcc": "toolchain-xtensa-esp32", - "xtensa-esp32s2-elf-gcc": "toolchain-xtensa-esp32s2", - "xtensa-esp32s3-elf-gcc": "toolchain-xtensa-esp32s3", - "riscv32-esp-elf-gcc": "toolchain-riscv32-esp", - } - - result = dict() - for tool in tool_deps: - if tool["name"] in toolchain_remap: - result[toolchain_remap[tool["name"]]] = _parse_version(tool["version"]) - - return result - - @staticmethod - def parse_tool_dependencies(index_data): - for package in index_data.get("packages", []): - if package["name"] == "esp32": - for platform in package["platforms"]: - if platform["name"] == "esp32": - return platform["toolsDependencies"] - - return [] - - @staticmethod - def download_remote_package_index(url_items): - def _prepare_url_for_index_file(url_items): - tag = "master" - if url_items.fragment: - tag = url_items.fragment - return ( - "https://raw.githubusercontent.com/%s/" - "%s/package/package_esp32_index.template.json" - % (url_items.path.replace(".git", ""), tag) - ) - - index_file_url = _prepare_url_for_index_file(url_items) - - try: - from platformio.public import fetch_http_content - content = fetch_http_content(index_file_url) - except ImportError: - import requests - content = requests.get(index_file_url, timeout=5).text - - return json.loads(content) - - def configure_arduino_toolchains(self, package_index): - if not package_index: - return - - toolchain_packages = self.extract_toolchain_versions( - self.parse_tool_dependencies(package_index) - ) - for toolchain_package, version in toolchain_packages.items(): - if toolchain_package not in self.packages: - self.packages[toolchain_package] = dict() - self.packages[toolchain_package]["version"] = version - self.packages[toolchain_package]["owner"] = "espressif" - self.packages[toolchain_package]["type"] = "toolchain" - - def configure_upstream_arduino_packages(self, url_items): - framework_index_file = os.path.join( - self.get_package_dir("framework-arduinoespressif32") or "", - "package", - "package_esp32_index.template.json", - ) - - # Detect whether the remote is already cloned - if os.path.isfile(framework_index_file) and os.path.isdir( - os.path.join( - self.get_package_dir("framework-arduinoespressif32") or "", ".git" - ) - ): - with open(framework_index_file) as fp: - self.configure_arduino_toolchains(json.load(fp)) - else: - print("Configuring toolchain packages from a remote source...") - self.configure_arduino_toolchains( - self.download_remote_package_index(url_items) - ) From 720dd9e2909e69e45b9b39db261acda78cc0613b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:26:35 +0200 Subject: [PATCH 004/175] Fix owner of --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index ef6d7eb..c8d1b92 100644 --- a/platform.json +++ b/platform.json @@ -50,13 +50,13 @@ "toolchain-xtensa-esp-elf": { "type": "toolchain", "optional": true, - "owner": "espressif", + "owner": "platformio", "version": "13.2.0+20240530" }, "toolchain-riscv32-esp": { "type": "toolchain", "optional": true, - "owner": "espressif", + "owner": "platformio", "version": "13.2.0+20240530" }, "toolchain-esp32ulp": { From cb93c63453008b1a16fa9905e38a433f5119f3a9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:37:41 +0200 Subject: [PATCH 005/175] ULP compability for IDF 5.3 --- builder/frameworks/ulp.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index eccd106..f99f182 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -13,6 +13,7 @@ # limitations under the License. import os +import sys from platformio import fs from platformio.util import get_systype @@ -34,11 +35,12 @@ ULP_BUILD_DIR = os.path.join( def prepare_ulp_env_vars(env): ulp_env.PrependENVPath("IDF_PATH", FRAMEWORK_DIR) + toolchain_path = platform.get_package_dir( + "toolchain-xtensa-esp-elf" + ) + additional_packages = [ - os.path.join( - platform.get_package_dir("toolchain-xtensa-%s" % idf_variant), - "bin", - ), + toolchain_path, os.path.join( platform.get_package_dir("toolchain-esp32ulp"), "bin", @@ -57,7 +59,7 @@ def prepare_ulp_env_vars(env): def collect_ulp_sources(): return [ - fs.to_unix_path(os.path.join(ulp_env.subst("$PROJECT_DIR"), "ulp", f)) + os.path.join(ulp_env.subst("$PROJECT_DIR"), "ulp", f) for f in os.listdir(os.path.join(ulp_env.subst("$PROJECT_DIR"), "ulp")) if f.endswith((".c", ".S", ".s")) ] @@ -95,7 +97,7 @@ def generate_ulp_config(target_config): "-riscv" if riscv_ulp_enabled else "", ), ), - "-DULP_S_SOURCES=%s" % ";".join([s.get_abspath() for s in source]), + "-DULP_S_SOURCES=%s" % ";".join([fs.to_unix_path(s.get_abspath()) for s in source]), "-DULP_APP_NAME=ulp_main", "-DCOMPONENT_DIR=" + os.path.join(ulp_env.subst("$PROJECT_DIR"), "ulp"), "-DCOMPONENT_INCLUDES=%s" % ";".join(get_component_includes(target_config)), @@ -110,7 +112,12 @@ def generate_ulp_config(target_config): os.path.join(FRAMEWORK_DIR, "components", "ulp", "cmake"), ) - exec_command(cmd) + print(555, cmd) + + result = exec_command(cmd) + if result["returncode"] != 0: + sys.stderr.write(result["err"] + "\n") + env.Exit(1) ulp_sources = collect_ulp_sources() ulp_sources.sort() From bbefb1c125a8cddafe2858c8146fd65ceb8fe38f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 30 Jul 2024 22:05:10 +0200 Subject: [PATCH 006/175] remove debug print --- builder/frameworks/ulp.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index f99f182..0c0073c 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -112,8 +112,6 @@ def generate_ulp_config(target_config): os.path.join(FRAMEWORK_DIR, "components", "ulp", "cmake"), ) - print(555, cmd) - result = exec_command(cmd) if result["returncode"] != 0: sys.stderr.write(result["err"] + "\n") From f7a586cc4c873f35c9cacf7895a7f12591c8304a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 7 Aug 2024 17:17:46 +0200 Subject: [PATCH 007/175] Fix bootloader offset code retrieve --- builder/frameworks/espidf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 656c853..9789749 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1668,7 +1668,7 @@ env.Prepend( ( board.get( "upload.bootloader_offset", - "0x0" if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32s3", "esp32h2") else ("0x2000" if mcu in ("esp32p4") else "0x1000"), + "0x0" if mcu in ["esp32c2", "esp32c3", "esp32c6", "esp32s3", "esp32h2"] else ("0x2000" if mcu in ["esp32p4"] else "0x1000"), ), os.path.join("$BUILD_DIR", "bootloader.bin"), ), From 2625ee402d525861c85f9a84a1856b40fbb20078 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 17 Aug 2024 12:58:04 +0200 Subject: [PATCH 008/175] Update esp32-c6-devkitc-1.json --- boards/esp32-c6-devkitc-1.json | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/esp32-c6-devkitc-1.json b/boards/esp32-c6-devkitc-1.json index b82e07f..a5732a1 100644 --- a/boards/esp32-c6-devkitc-1.json +++ b/boards/esp32-c6-devkitc-1.json @@ -8,6 +8,7 @@ "variant": "esp32c6" }, "connectivity": [ + "bluetooth", "wifi" ], "debug": { From d0ef23ccebb49ee9d58d2682537248c8f6cd6813 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 19 Aug 2024 22:50:03 +0200 Subject: [PATCH 009/175] use espressif Arduino branch `release/v3.1.x` --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index c8d1b92..ccc6cbc 100644 --- a/platform.json +++ b/platform.json @@ -33,13 +33,13 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/master.zip" + "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/release/v3.1.x.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/esp32-arduino-libs/archive/refs/heads/idf-release/v5.1.zip" + "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-466a392a.zip" }, "framework-espidf": { "type": "framework", From abf68b3c7bb9f36d96e34fe26d78cd064bafd70d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:28:25 +0200 Subject: [PATCH 010/175] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 92e0043..fc249b2 100644 --- a/README.md +++ b/README.md @@ -45,12 +45,12 @@ board = ... ... ``` -### Development version -espressif Arduino repo branch master and latest compiled Arduino libs +### Bleeding edged development version +based on devel branch Arduino 3.1.0 and IDF 5.3.0 ```ini [env:development] -platform = https://github.com/pioarduino/platform-espressif32.git#develop +platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53 board = ... ... ``` From 5106663441f69915d8f7f8fe0ee0abe232401262 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:04:37 +0200 Subject: [PATCH 011/175] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc249b2..126ef04 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,13 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Configure a platform option in [platformio.ini](https://docs.platformio.org/page/projectconf.html) file: ### Stable version -espressif Arduino 3.0.3 and IDF 5.1.4 +espressif Arduino 3.0.4 and IDF 5.1.4 See `platform` [documentation](https://docs.platformio.org/en/latest/projectconf/sections/env/options/platform/platform.html#projectconf-env-platform) for details. ```ini [env:stable] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = ... ... ``` From 13f08469b577824ce47cd94320a1788128c45075 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:59:56 +0200 Subject: [PATCH 012/175] Fix compile issue with managed components --- builder/frameworks/espidf.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 9789749..990fc35 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -53,12 +53,14 @@ if os.environ.get("PYTHONPATH"): env = DefaultEnvironment() env.SConscript("_embed_files.py", exports="env") +# Allow changes in folders of managed components +os.environ["IDF_COMPONENT_OVERWRITE_MANAGED_COMPONENTS"] = "1" + platform = env.PioPlatform() board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") idf_variant = mcu.lower() -# Required until Arduino switches to v5 IDF5 = ( platform.get_package_version("framework-espidf") .split(".")[1] @@ -655,7 +657,8 @@ def generate_project_ld_script(sdk_config, ignore_targets=None): "sections.ld.in", ) - if IDF5: + framework_version = [int(v) for v in get_framework_version().split(".")] + if framework_version[:2] > [5, 2]: initial_ld_script = preprocess_linker_file( initial_ld_script, os.path.join( @@ -1257,7 +1260,7 @@ def install_python_deps(): "future": ">=0.18.3", "pyparsing": ">=3.1.0,<4" if IDF5 else ">=2.0.3,<2.4.0", "kconfiglib": "~=14.1.0" if IDF5 else "~=13.7.1", - "idf-component-manager": "~=1.5.2" if IDF5 else "~=1.0", + "idf-component-manager": "~=2.0.1" if IDF5 else "~=1.0", "esp-idf-kconfig": ">=1.4.2,<2.0.0" } @@ -1414,7 +1417,8 @@ if not board.get("build.ldscript", ""): "memory.ld.in", )) - if IDF5: + framework_version = [int(v) for v in get_framework_version().split(".")] + if framework_version[:2] > [5, 2]: initial_ld_script = preprocess_linker_file( initial_ld_script, os.path.join( From 017ffd098a92c55a7aef179b10ca39699c5d46a4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:05:43 +0200 Subject: [PATCH 013/175] use latest Arduino 3.1.0 libs --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index ccc6cbc..1db0315 100644 --- a/platform.json +++ b/platform.json @@ -39,7 +39,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-466a392a.zip" + "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-0526c35e.zip" }, "framework-espidf": { "type": "framework", From ecbd68f187f02b3429b4a9d1d12fcf15c14d4c82 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:50:07 +0200 Subject: [PATCH 014/175] fetch Arduino libs dl URL from manifest json --- platform.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform.py b/platform.py index 03b118d..99cb138 100644 --- a/platform.py +++ b/platform.py @@ -37,6 +37,11 @@ class Espressif32Platform(PlatformBase): if "arduino" in frameworks: self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False + # use latest espressif Arduino libs + URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/idf-release/v5.3/package/package_esp32_index.template.json" + packjdata = requests.get(URL).json() + dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] + self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url if "buildfs" in targets: filesystem = variables.get("board_build.filesystem", "littlefs") From 3c69c8adeedac163a847bdf7820c793ba6103adc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:51:01 +0200 Subject: [PATCH 015/175] fetch Arduino libs dl URL from manifest json --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 1db0315..1c52621 100644 --- a/platform.json +++ b/platform.json @@ -39,7 +39,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-0526c35e.zip" + "version": "" }, "framework-espidf": { "type": "framework", From 51ecab12ae6d6e4bcd1948ca56302f467c3f998b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:09:14 +0200 Subject: [PATCH 016/175] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 126ef04..81434d1 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and Bluetooth. ESP32 integrates an antenna switch, RF balun, power amplifier, low-noise receive amplifier, filters, and power management modules. * [Documentation](https://docs.platformio.org/page/platforms/espressif32.html) (advanced usage, packages, boards, frameworks, etc.) +* Issues with boards (wrong / missing). All issues caused from boards will not be fixed from the maintainer(s). A PR needs to be provided to solve. ## IDE Preparation From 29ac567616a5b98e32a257fa2850c3bdaea96d84 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 29 Aug 2024 21:21:58 +0200 Subject: [PATCH 017/175] Fix IDF 5.3 ULP compile --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index 1c52621..1313d32 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "53.03.03+develop", + "version": "53.03.10+develop", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.0/esp-idf-v5.3.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.0.ulp/esp-idf-v5.3.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From b25578dab1ded5341361b6efbc99e767d98250b2 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 29 Aug 2024 21:29:44 +0200 Subject: [PATCH 018/175] Use espressif Arduino branch release/v3.1.x --- platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.py b/platform.py index 99cb138..10a5711 100644 --- a/platform.py +++ b/platform.py @@ -38,7 +38,7 @@ class Espressif32Platform(PlatformBase): self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False # use latest espressif Arduino libs - URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/idf-release/v5.3/package/package_esp32_index.template.json" + URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/release/v3.1.x/package/package_esp32_index.template.json" packjdata = requests.get(URL).json() dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url From e3955e2bfa0e06af7a6299afdb84e93386224568 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:08:11 +0200 Subject: [PATCH 019/175] Update platform.py --- platform.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform.py b/platform.py index 10a5711..8c47794 100644 --- a/platform.py +++ b/platform.py @@ -23,6 +23,11 @@ from platformio.public import PlatformBase, to_unix_path IS_WINDOWS = sys.platform.startswith("win") +# Set Platformio env var to use windows_amd64 for all windows architectures +# only windows_amd64 native espressif toolchains are available +# needs platformio core >= 6.1.16b2 or pioarduino core 6.1.16+test +if IS_WINDOWS: + os.environ["PLATFORMIO_SYSTEM_TYPE"] = "windows_amd64" class Espressif32Platform(PlatformBase): From b2eac3c1451a1117aad14b77ff16f41200b313ff Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:58:43 +0200 Subject: [PATCH 020/175] better handling of complex Macros from cmake model --- builder/frameworks/espidf.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 990fc35..9313117 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -326,8 +326,9 @@ def extract_defines(compile_group): define_string = define_string.strip() if "=" in define_string: define, value = define_string.split("=", maxsplit=1) - if '"' in value and not value.startswith("\\"): - # Escape only raw values + if any(char in value for char in (' ', '<', '>')): + value = f'"{value}"' + elif '"' in value and not value.startswith("\\"): value = value.replace('"', '\\"') return (define, value) return define_string @@ -338,8 +339,11 @@ def extract_defines(compile_group): ] for f in compile_group.get("compileCommandFragments", []): - if f.get("fragment", "").startswith("-D"): - result.append(_normalize_define(f["fragment"][2:])) + fragment = f.get("fragment", "").strip() + if fragment.startswith('"'): + fragment = fragment.strip('"') + if fragment.startswith("-D"): + result.append(_normalize_define(fragment[2:])) return result From 2642ed8da7861c56732b9200437095a9be49d90b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 6 Sep 2024 23:55:07 +0200 Subject: [PATCH 021/175] IDF 5.3.1 release --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 1313d32..e6e7866 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.0.ulp/esp-idf-v5.3.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.ulp/esp-idf-v5.3.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 52fc97538fd5efbd5d9d372f8ab0d942e1e3d94e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:45:59 +0200 Subject: [PATCH 022/175] fix handling of cc fragments --- builder/frameworks/espidf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 9313117..cfabb28 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -429,8 +429,8 @@ def get_app_flags(app_config, default_config): for cg in config["compileGroups"]: flags[cg["language"]] = [] for ccfragment in cg["compileCommandFragments"]: - fragment = ccfragment.get("fragment", "") - if not fragment.strip() or fragment.startswith("-D"): + fragment = ccfragment.get("fragment", "").strip("\" ") + if not fragment or fragment.startswith("-D"): continue flags[cg["language"]].extend( click.parser.split_arg_string(fragment.strip()) @@ -715,7 +715,7 @@ def prepare_build_envs(config, default_env, debug_allowed=True): build_env = default_env.Clone() build_env.SetOption("implicit_cache", 1) for cc in compile_commands: - build_flags = cc.get("fragment") + build_flags = cc.get("fragment", "").strip("\" ") if not build_flags.startswith("-D"): if build_flags.startswith("-include") and ".." in build_flags: source_index = cg.get("sourceIndexes")[0] From a72dfbfcd7954cce28104976059cc7d834a261c1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:58:04 +0200 Subject: [PATCH 023/175] unchanged IDF 5.3.1 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index e6e7866..59b3e9e 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.ulp/esp-idf-v5.3.1.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1/esp-idf-v5.3.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 69442f2316e13c5c6bf3230a29a5aad4313e3d83 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:01:27 +0200 Subject: [PATCH 024/175] ULP has now a cmake build script --- builder/frameworks/ulp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index 0c0073c..7933bd9 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -105,7 +105,7 @@ def generate_ulp_config(target_config): "-DIDF_PATH=" + fs.to_unix_path(FRAMEWORK_DIR), "-DSDKCONFIG_HEADER=" + os.path.join(BUILD_DIR, "config", "sdkconfig.h"), "-DPYTHON=" + env.subst("$PYTHONEXE"), - "-DULP_COCPU_IS_RISCV=%s" % ("ON" if riscv_ulp_enabled else "OFF"), + "-DSDKCONFIG_CMAKE=" + os.path.join(BUILD_DIR, "config", "sdkconfig.cmake"), "-GNinja", "-B", ULP_BUILD_DIR, From 5b1960f5e828378ab02febac9c35cf1c2282a9b3 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 13 Sep 2024 17:55:43 +0200 Subject: [PATCH 025/175] add arduino/idf examples --- .github/workflows/examples.yml | 2 + .../espidf-arduino-h2zero-BLE_scan/.gitignore | 2 + .../CMakeLists.txt | 4 + .../espidf-arduino-h2zero-BLE_scan/README.md | 7 + .../include/README | 39 ++ .../espidf-arduino-h2zero-BLE_scan/lib/README | 46 +++ .../platformio.ini | 27 ++ .../sdkconfig.defaults | 34 ++ .../src/CMakeLists.txt | 6 + .../src/idf_component.yml | 40 ++ .../src/main.cpp | 54 +++ .../CMakeLists.txt | 23 ++ .../espidf-arduino-matter-light/README.md | 3 + .../include/README | 39 ++ .../espidf-arduino-matter-light/lib/README | 46 +++ .../main/CMakeLists.txt | 9 + .../main/builtinLED.cpp | 251 ++++++++++++ .../main/builtinLED.h | 76 ++++ .../main/idf_component.yml | 3 + .../main/matter_accessory_driver.cpp | 101 +++++ .../main/matter_accessory_driver.h | 28 ++ .../main/matter_light.cpp | 369 ++++++++++++++++++ .../partitions.csv | 9 + .../platformio.ini | 26 ++ .../sdkconfig.defaults | 66 ++++ .../espidf-arduino-matter-light/test/README | 11 + 26 files changed, 1321 insertions(+) create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/.gitignore create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/CMakeLists.txt create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/README.md create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/include/README create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/lib/README create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/platformio.ini create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/sdkconfig.defaults create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/src/CMakeLists.txt create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml create mode 100644 examples/espidf-arduino-h2zero-BLE_scan/src/main.cpp create mode 100644 examples/espidf-arduino-matter-light/CMakeLists.txt create mode 100644 examples/espidf-arduino-matter-light/README.md create mode 100644 examples/espidf-arduino-matter-light/include/README create mode 100644 examples/espidf-arduino-matter-light/lib/README create mode 100644 examples/espidf-arduino-matter-light/main/CMakeLists.txt create mode 100644 examples/espidf-arduino-matter-light/main/builtinLED.cpp create mode 100644 examples/espidf-arduino-matter-light/main/builtinLED.h create mode 100644 examples/espidf-arduino-matter-light/main/idf_component.yml create mode 100644 examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp create mode 100644 examples/espidf-arduino-matter-light/main/matter_accessory_driver.h create mode 100644 examples/espidf-arduino-matter-light/main/matter_light.cpp create mode 100644 examples/espidf-arduino-matter-light/partitions.csv create mode 100644 examples/espidf-arduino-matter-light/platformio.ini create mode 100644 examples/espidf-arduino-matter-light/sdkconfig.defaults create mode 100644 examples/espidf-arduino-matter-light/test/README diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index a9e0352..0ed9246 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -18,6 +18,8 @@ jobs: - "examples/arduino-rmt-blink" - "examples/arduino-usb-keyboard" - "examples/arduino-wifiscan" + - "examples/espidf-arduino-h2zero-BLE_scan" + - "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" - "examples/espidf-blink" diff --git a/examples/espidf-arduino-h2zero-BLE_scan/.gitignore b/examples/espidf-arduino-h2zero-BLE_scan/.gitignore new file mode 100644 index 0000000..b9f3806 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/.gitignore @@ -0,0 +1,2 @@ +.pio +.vscode diff --git a/examples/espidf-arduino-h2zero-BLE_scan/CMakeLists.txt b/examples/espidf-arduino-h2zero-BLE_scan/CMakeLists.txt new file mode 100644 index 0000000..b6275f6 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.16.0) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +add_compile_definitions(ARDUINO_ARCH_ESP32=1) +project(Arduino_IDF_BLE_scan) diff --git a/examples/espidf-arduino-h2zero-BLE_scan/README.md b/examples/espidf-arduino-h2zero-BLE_scan/README.md new file mode 100644 index 0000000..5601e54 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/README.md @@ -0,0 +1,7 @@ +# Arduino_IDF_BLE_scan example using 3rd party NimBLE stack + +BLE scan example, using the great h2zero NimBLE implementation. The needed NimBLE lib is loaded via the IDF component manager -> `idf_component.yml`. +Mandantory not to forget to switch Arduino included BLE libs. +Done in `sdkconfig.defaults` + +Thx @h2zero for the great BLE library. diff --git a/examples/espidf-arduino-h2zero-BLE_scan/include/README b/examples/espidf-arduino-h2zero-BLE_scan/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/espidf-arduino-h2zero-BLE_scan/lib/README b/examples/espidf-arduino-h2zero-BLE_scan/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/espidf-arduino-h2zero-BLE_scan/platformio.ini b/examples/espidf-arduino-h2zero-BLE_scan/platformio.ini new file mode 100644 index 0000000..7b9a517 --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/platformio.ini @@ -0,0 +1,27 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env] +platform = espressif32 +framework = arduino, espidf +monitor_speed = 115200 +board_build.embed_txtfiles = + managed_components/espressif__esp_insights/server_certs/https_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt +lib_ignore = + BLE + BluetoothSerial + SimpleBLE + WiFiProv + +[env:esp32] +board = esp32dev diff --git a/examples/espidf-arduino-h2zero-BLE_scan/sdkconfig.defaults b/examples/espidf-arduino-h2zero-BLE_scan/sdkconfig.defaults new file mode 100644 index 0000000..267ca7f --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/sdkconfig.defaults @@ -0,0 +1,34 @@ +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_WS2812_LED_ENABLE is not set +CONFIG_FREERTOS_HZ=1000 +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y + +# Override some defaults so BT stack is enabled +# in this example +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y + +# +# Arduino Configuration +# +# +# Disable all Arduino included BLE libraries +# +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +# CONFIG_ARDUINO_SELECTIVE_WiFiProv is not set +# CONFIG_ARDUINO_SELECTIVE_BLE is not set +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set +# end of Arduino Configuration \ No newline at end of file diff --git a/examples/espidf-arduino-h2zero-BLE_scan/src/CMakeLists.txt b/examples/espidf-arduino-h2zero-BLE_scan/src/CMakeLists.txt new file mode 100644 index 0000000..483bc0c --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml b/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml new file mode 100644 index 0000000..98b4cbf --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml @@ -0,0 +1,40 @@ +dependencies: + # Required IDF version + idf: ">=4.4" + + esp-nimble-cpp: + git: https://github.com/h2zero/esp-nimble-cpp.git + + + # # Defining a dependency from the registry: + # # https://components.espressif.com/component/example/cmp + # example/cmp: "^3.3.3" # Automatically update minor releases + # + # # Other ways to define dependencies + # + # # For components maintained by Espressif only name can be used. + # # Same as `espressif/cmp` + # component: "~1.0.0" # Automatically update bugfix releases + # + # # Or in a longer form with extra parameters + # component2: + # version: ">=2.0.0" + # + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect for the `main` component. + # # All dependencies of `main` are public by default. + # public: true + # + # # For components hosted on non-default registry: + # service_url: "https://componentregistry.company.com" + # + # # For components in git repository: + # test_component: + # path: test_component + # git: ssh://git@gitlab.com/user/components.git + # + # # For test projects during component development + # # components can be used from a local directory + # # with relative or absolute path + # some_local_component: + # path: ../../projects/component diff --git a/examples/espidf-arduino-h2zero-BLE_scan/src/main.cpp b/examples/espidf-arduino-h2zero-BLE_scan/src/main.cpp new file mode 100644 index 0000000..04b6e5f --- /dev/null +++ b/examples/espidf-arduino-h2zero-BLE_scan/src/main.cpp @@ -0,0 +1,54 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp + Ported to Arduino ESP32 by Evandro Copercini + Refactored back to IDF by H2zero +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +#include +***********************/ + +#include + +#include + +extern "C"{void app_main(void);} + +int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever +BLEScan* pBLEScan; + +class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { + void onResult(BLEAdvertisedDevice* advertisedDevice) { + printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); + } +}; + +void scanTask (void * parameter){ + for(;;) { + // put your main code here, to run repeatedly: + BLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); + printf("Devices found: %d\n", foundDevices.getCount()); + printf("Scan done!\n"); + pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory + vTaskDelay(2000/portTICK_PERIOD_MS); // Delay a second between loops. + } + + vTaskDelete(NULL); +} + +void app_main(void) { + printf("Scanning...\n"); + + BLEDevice::init(""); + pBLEScan = BLEDevice::getScan(); //create new scan + pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); // less or equal setInterval value + xTaskCreate(scanTask, "scanTask", 5000, NULL, 1, NULL); +} diff --git a/examples/espidf-arduino-matter-light/CMakeLists.txt b/examples/espidf-arduino-matter-light/CMakeLists.txt new file mode 100644 index 0000000..4a9c0c2 --- /dev/null +++ b/examples/espidf-arduino-matter-light/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.16.0) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(PROJECT_VER "1.0") +set(PROJECT_VER_NUMBER 1) + +project(matter-light) + + +# WARNING: This is just an example for using key for decrypting the encrypted OTA image +# Please do not use it as is. +if(CONFIG_ENABLE_ENCRYPTED_OTA) + target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT) +endif() + +if(CONFIG_IDF_TARGET_ESP32C2) + include(relinker) +endif() + +idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND) +idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND) +# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various +# flags that depend on -Wformat +idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND) \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/README.md b/examples/espidf-arduino-matter-light/README.md new file mode 100644 index 0000000..fd3f77f --- /dev/null +++ b/examples/espidf-arduino-matter-light/README.md @@ -0,0 +1,3 @@ +## Arduino/IDF Matter Light example + +The needed Matter component is added via the IDF component manager -> `idf_component.yml`. diff --git a/examples/espidf-arduino-matter-light/include/README b/examples/espidf-arduino-matter-light/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/espidf-arduino-matter-light/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/espidf-arduino-matter-light/lib/README b/examples/espidf-arduino-matter-light/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/examples/espidf-arduino-matter-light/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/espidf-arduino-matter-light/main/CMakeLists.txt b/examples/espidf-arduino-matter-light/main/CMakeLists.txt new file mode 100644 index 0000000..dfe4b75 --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/CMakeLists.txt @@ -0,0 +1,9 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/main/*.*) + +idf_component_register(SRCS ${app_sources}) + +#set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) +#target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/main/builtinLED.cpp b/examples/espidf-arduino-matter-light/main/builtinLED.cpp new file mode 100644 index 0000000..cb7135e --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/builtinLED.cpp @@ -0,0 +1,251 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + + This will implement the onboard WS2812b LED as a LED indicator + It can be used to indicate some state or status of the device + The LED can be controlled using RGB, HSV or color temperature, brightness + + In this example, the LED Indicator class is used as the Matter light accessory +*/ + +#include +#include "builtinLED.h" + +typedef struct { + uint16_t hue; + uint8_t saturation; +} HS_color_t; + +static const HS_color_t temperatureTable[] = { + {4, 100}, {8, 100}, {11, 100}, {14, 100}, {16, 100}, {18, 100}, {20, 100}, {22, 100}, {24, 100}, {25, 100}, + {27, 100}, {28, 100}, {30, 100}, {31, 100}, {31, 95}, {30, 89}, {30, 85}, {29, 80}, {29, 76}, {29, 73}, + {29, 69}, {28, 66}, {28, 63}, {28, 60}, {28, 57}, {28, 54}, {28, 52}, {27, 49}, {27, 47}, {27, 45}, + {27, 43}, {27, 41}, {27, 39}, {27, 37}, {27, 35}, {27, 33}, {27, 31}, {27, 30}, {27, 28}, {27, 26}, + {27, 25}, {27, 23}, {27, 22}, {27, 21}, {27, 19}, {27, 18}, {27, 17}, {27, 15}, {28, 14}, {28, 13}, + {28, 12}, {29, 10}, {29, 9}, {30, 8}, {31, 7}, {32, 6}, {34, 5}, {36, 4}, {41, 3}, {49, 2}, + {0, 0}, {294, 2}, {265, 3}, {251, 4}, {242, 5}, {237, 6}, {233, 7}, {231, 8}, {229, 9}, {228, 10}, + {227, 11}, {226, 11}, {226, 12}, {225, 13}, {225, 13}, {224, 14}, {224, 14}, {224, 15}, {224, 15}, {223, 16}, + {223, 16}, {223, 17}, {223, 17}, {223, 17}, {222, 18}, {222, 18}, {222, 19}, {222, 19}, {222, 19}, {222, 19}, + {222, 20}, {222, 20}, {222, 20}, {222, 21}, {222, 21} +}; + +/* step brightness table: gamma = 2.3 */ +static const uint8_t gamma_table[MAX_PROGRESS] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, + 26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 86, + 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, + 108, 110, 111, 112, 114, 115, 117, 118, 120, 121, 123, 124, 126, 128, 129, 131, + 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 149, 150, 152, 154, 156, 157, + 159, 161, 163, 164, 166, 168, 170, 172, 174, 175, 177, 179, 181, 183, 185, 187, + 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, + 221, 223, 226, 228, 230, 232, 234, 236, 239, 241, 243, 245, 248, 250, 252, 255, +}; + +BuiltInLED::BuiltInLED() { + pin_number = (uint8_t) -1; // no pin number + state = false; // LED is off + hsv_color.value = 0; // black color +} + +BuiltInLED::~BuiltInLED(){ + end(); +} + +led_indicator_color_hsv_t BuiltInLED::rgb2hsv(led_indicator_color_rgb_t rgb) { + led_indicator_color_hsv_t hsv; + uint8_t minRGB, maxRGB; + uint8_t delta; + + minRGB = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b); + maxRGB = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b); + hsv.value = 0; + hsv.v = maxRGB; + delta = maxRGB - minRGB; + + if (delta == 0) { + hsv.h = 0; + hsv.s = 0; + } else { + hsv.s = delta * 255 / maxRGB; + + if (rgb.r == maxRGB) { + hsv.h = (60 * (rgb.g - rgb.b) / delta + 360) % 360; + } else if (rgb.g == maxRGB) { + hsv.h = (60 * (rgb.b - rgb.r) / delta + 120); + } else { + hsv.h = (60 * (rgb.r - rgb.g) / delta + 240); + } + } + return hsv; +} + +led_indicator_color_rgb_t BuiltInLED::hsv2rgb(led_indicator_color_hsv_t hsv) { + led_indicator_color_rgb_t rgb; + uint8_t rgb_max = hsv.v; + uint8_t rgb_min = rgb_max * (255 - hsv.s) / 255.0f; + + uint8_t i = hsv.h / 60; + uint8_t diff = hsv.h % 60; + + // RGB adjustment amount by hue + uint8_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + rgb.value = 0; + switch (i) { + case 0: + rgb.r = rgb_max; + rgb.g = rgb_min + rgb_adj; + rgb.b = rgb_min; + break; + case 1: + rgb.r = rgb_max - rgb_adj; + rgb.g = rgb_max; + rgb.b = rgb_min; + break; + case 2: + rgb.r = rgb_min; + rgb.g = rgb_max; + rgb.b = rgb_min + rgb_adj; + break; + case 3: + rgb.r = rgb_min; + rgb.g = rgb_max - rgb_adj; + rgb.b = rgb_max; + break; + case 4: + rgb.r = rgb_min + rgb_adj; + rgb.g = rgb_min; + rgb.b = rgb_max; + break; + default: + rgb.r = rgb_max; + rgb.g = rgb_min; + rgb.b = rgb_max - rgb_adj; + break; + } + + // gamma correction + rgb.r = gamma_table[rgb.r]; + rgb.g = gamma_table[rgb.g]; + rgb.b = gamma_table[rgb.b]; + return rgb; +} + +void BuiltInLED::begin(uint8_t pin){ + if (pin < NUM_DIGITAL_PINS) { + pin_number = pin; + write(); + } else { + log_e("Invalid pin (%d) number", pin); + } +} +void BuiltInLED::end(){ + state = false; + write(); + if (pin_number < NUM_DIGITAL_PINS) { + if (!rmtDeinit(pin_number)) { + log_e("Failed to deinitialize RMT"); + } + } +} + +void BuiltInLED::on(){ + state = true; +} + +void BuiltInLED::off(){ + state = false; +} + +void BuiltInLED::toggle(){ + state = !state; +} + +bool BuiltInLED::getState(){ + return state; +} + +bool BuiltInLED::write(){ + led_indicator_color_rgb_t rgb_color = getRGB(); + log_d("Writing to pin %d with state = %s", pin_number, state ? "ON" : "OFF"); + log_d("HSV: %d, %d, %d", hsv_color.h, hsv_color.s, hsv_color.v); + log_d("RGB: %d, %d, %d", rgb_color.r, rgb_color.g, rgb_color.b); + if(pin_number < NUM_DIGITAL_PINS){ + if (state) { + rgbLedWrite(pin_number, rgb_color.r, rgb_color.g, rgb_color.b); + } else { + rgbLedWrite(pin_number, 0, 0, 0); + } + return true; + } else { + log_e("Invalid pin (%d) number", pin_number); + return false; + } +} + +void BuiltInLED::setBrightness(uint8_t brightness){ + hsv_color.v = brightness; +} + +uint8_t BuiltInLED::getBrightness(){ + return hsv_color.v; +} + +void BuiltInLED::setHSV(led_indicator_color_hsv_t hsv){ + if (hsv.h > MAX_HUE) { + hsv.h = MAX_HUE; + } + hsv_color.value = hsv.value; +} + +led_indicator_color_hsv_t BuiltInLED::getHSV(){ + return hsv_color; +} + +void BuiltInLED::setRGB(led_indicator_color_rgb_t rgb_color){ + hsv_color = rgb2hsv(rgb_color); +} + +led_indicator_color_rgb_t BuiltInLED::getRGB(){ + return hsv2rgb(hsv_color); +} + +void BuiltInLED::setTemperature(uint32_t temperature){ + uint16_t hue; + uint8_t saturation; + + log_d("Requested Temperature: %ld", temperature); + //hsv_color.v = gamma_table[((temperature >> 25) & 0x7F)]; + temperature &= 0xFFFFFF; + if (temperature < 600) { + hue = 0; + saturation = 100; + } else { + if (temperature > 10000) { + hue = 222; + saturation = 21 + (temperature - 10000) * 41 / 990000; + } else { + temperature -= 600; + temperature /= 100; + hue = temperatureTable[temperature].hue; + saturation = temperatureTable[temperature].saturation; + } + } + saturation = (saturation * 255) / 100; + // brightness is not changed + hsv_color.h = hue; + hsv_color.s = saturation; + log_d("Calculated Temperature: %ld, Hue: %d, Saturation: %d, Brightness: %d", temperature, hue, saturation, hsv_color.v); +} + diff --git a/examples/espidf-arduino-matter-light/main/builtinLED.h b/examples/espidf-arduino-matter-light/main/builtinLED.h new file mode 100644 index 0000000..85fc171 --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/builtinLED.h @@ -0,0 +1,76 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + + This will implement the onboard WS2812b LED as a LED indicator + It can be used to indicate some state or status of the device + The LED can be controlled using RGB, HSV or color temperature, brightness + + In this example, the BuiltInLED class is used as the Matter light accessory +*/ + +#pragma once + +#include + +#define MAX_HUE 360 +#define MAX_SATURATION 255 +#define MAX_BRIGHTNESS 255 +#define MAX_PROGRESS 256 + +typedef struct { + union { + struct { + uint32_t v: 8; /*!< Brightness/Value of the LED. 0-255 */ + uint32_t s: 8; /*!< Saturation of the LED. 0-255 */ + uint32_t h: 9; /*!< Hue of the LED. 0-360 */ + }; + uint32_t value; /*!< IHSV value of the LED. */ + }; +} led_indicator_color_hsv_t; + +typedef struct { + union { + struct { + uint32_t r: 8; /*!< Red component of the LED color. Range: 0-255. */ + uint32_t g: 8; /*!< Green component of the LED color. Range: 0-255. */ + uint32_t b: 8; /*!< Blue component of the LED color. Range: 0-255. */ + }; + uint32_t value; /*!< Combined RGB value of the LED color. */ + }; +} led_indicator_color_rgb_t; + +class BuiltInLED { +private: + uint8_t pin_number; + bool state; + led_indicator_color_hsv_t hsv_color; + +public: + BuiltInLED(); + ~BuiltInLED(); + + static led_indicator_color_hsv_t rgb2hsv(led_indicator_color_rgb_t rgb_value); + static led_indicator_color_rgb_t hsv2rgb(led_indicator_color_hsv_t hsv); + + void begin(uint8_t pin); + void end(); + + void on(); + void off(); + void toggle(); + bool getState(); + + bool write(); + + void setBrightness(uint8_t brightness); + uint8_t getBrightness(); + void setHSV(led_indicator_color_hsv_t hsv); + led_indicator_color_hsv_t getHSV(); + void setRGB(led_indicator_color_rgb_t color); + led_indicator_color_rgb_t getRGB(); + void setTemperature(uint32_t temperature); +}; diff --git a/examples/espidf-arduino-matter-light/main/idf_component.yml b/examples/espidf-arduino-matter-light/main/idf_component.yml new file mode 100644 index 0000000..369a76b --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + espressif/esp_matter: + version: "^1.3.0" \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp new file mode 100644 index 0000000..9fe2b16 --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp @@ -0,0 +1,101 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include +#include "builtinLED.h" +#include "matter_accessory_driver.h" + +// set your board WS2812b pin here (e.g. 48 is the default pin for the ESP32-S3 devkit) +#define WS2812_PIN 48 + +/* Do any conversions/remapping for the actual value here */ +esp_err_t light_accessory_set_power(void *led, uint8_t val) +{ + BuiltInLED *builtinLED = (BuiltInLED *) led; + esp_err_t err = ESP_OK; + if (val) { + builtinLED->on(); + } else { + builtinLED->off(); + } + if (!builtinLED->write()) { + err = ESP_FAIL; + } + log_i("LED set power: %d", val); + return err; +} + +esp_err_t light_accessory_set_brightness(void *led, uint8_t val) +{ + esp_err_t err = ESP_OK; + BuiltInLED *builtinLED = (BuiltInLED *) led; + int value = REMAP_TO_RANGE(val, MATTER_BRIGHTNESS, STANDARD_BRIGHTNESS); + + builtinLED->setBrightness(value); + if (!builtinLED->write()) { + err = ESP_FAIL; + } + log_i("LED set brightness: %d", value); + return err; +} + +esp_err_t light_accessory_set_hue(void *led, uint8_t val) +{ + esp_err_t err = ESP_OK; + BuiltInLED *builtinLED = (BuiltInLED *) led; + int value = REMAP_TO_RANGE(val, MATTER_HUE, STANDARD_HUE); + led_indicator_color_hsv_t hsv = builtinLED->getHSV(); + hsv.h = value; + builtinLED->setHSV(hsv); + if (!builtinLED->write()) { + err = ESP_FAIL; + } + log_i("LED set hue: %d", value); + return err; +} + +esp_err_t light_accessory_set_saturation(void *led, uint8_t val) +{ + esp_err_t err = ESP_OK; + BuiltInLED *builtinLED = (BuiltInLED *) led; + int value = REMAP_TO_RANGE(val, MATTER_SATURATION, STANDARD_SATURATION); + led_indicator_color_hsv_t hsv = builtinLED->getHSV(); + hsv.s = value; + builtinLED->setHSV(hsv); + if (!builtinLED->write()) { + err = ESP_FAIL; + } + log_i("LED set saturation: %d", value); + return err; +} + +esp_err_t light_accessory_set_temperature(void *led, uint16_t val) +{ + esp_err_t err = ESP_OK; + BuiltInLED *builtinLED = (BuiltInLED *) led; + uint32_t value = REMAP_TO_RANGE_INVERSE(val, STANDARD_TEMPERATURE_FACTOR); + builtinLED->setTemperature(value); + if (!builtinLED->write()) { + err = ESP_FAIL; + } + log_i("LED set temperature: %ld", value); + return err; +} + +app_driver_handle_t light_accessory_init() +{ + /* Initialize led */ + static BuiltInLED builtinLED; + + const uint8_t pin = WS2812_PIN; // set your board WS2812b pin here + builtinLED.begin(pin); + builtinLED.setHSV({DEFAULT_HUE, DEFAULT_SATURATION, DEFAULT_BRIGHTNESS}); + builtinLED.write(); + return (app_driver_handle_t) &builtinLED; +} diff --git a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h new file mode 100644 index 0000000..b3b6692 --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h @@ -0,0 +1,28 @@ +#include + +/** Standard max values (used for remapping attributes) */ +#define STANDARD_BRIGHTNESS 255 +#define STANDARD_HUE 360 +#define STANDARD_SATURATION 255 +#define STANDARD_TEMPERATURE_FACTOR 1000000 + +/** Matter max values (used for remapping attributes) */ +#define MATTER_BRIGHTNESS 254 +#define MATTER_HUE 254 +#define MATTER_SATURATION 254 +#define MATTER_TEMPERATURE_FACTOR 1000000 + +/** Default attribute values used during initialization */ +#define DEFAULT_POWER true +#define DEFAULT_BRIGHTNESS 64 +#define DEFAULT_HUE 128 +#define DEFAULT_SATURATION 254 + +typedef void *app_driver_handle_t; + +esp_err_t light_accessory_set_power(void *led, uint8_t val); +esp_err_t light_accessory_set_brightness(void *led, uint8_t val); +esp_err_t light_accessory_set_hue(void *led, uint8_t val); +esp_err_t light_accessory_set_saturation(void *led, uint8_t val); +esp_err_t light_accessory_set_temperature(void *led, uint16_t val); +app_driver_handle_t light_accessory_init(); diff --git a/examples/espidf-arduino-matter-light/main/matter_light.cpp b/examples/espidf-arduino-matter-light/main/matter_light.cpp new file mode 100644 index 0000000..76d5cfe --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/matter_light.cpp @@ -0,0 +1,369 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "matter_accessory_driver.h" + +#include + +#include +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#include "esp_openthread_types.h" + +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } + +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_NONE, \ + } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \ + } +#endif + +uint16_t light_endpoint_id = 0; + +using namespace esp_matter; +using namespace esp_matter::attribute; +using namespace esp_matter::endpoint; +using namespace chip::app::Clusters; + +constexpr auto k_timeout_seconds = 300; + +#if CONFIG_ENABLE_ENCRYPTED_OTA +extern const char decryption_key_start[] asm("_binary_esp_image_encryption_key_pem_start"); +extern const char decryption_key_end[] asm("_binary_esp_image_encryption_key_pem_end"); + +static const char *s_decryption_key = decryption_key_start; +static const uint16_t s_decryption_key_len = decryption_key_end - decryption_key_start; +#endif // CONFIG_ENABLE_ENCRYPTED_OTA + +static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) +{ + switch (event->Type) { + case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged: + log_i("Interface IP Address changed"); + break; + + case chip::DeviceLayer::DeviceEventType::kCommissioningComplete: + log_i("Commissioning complete"); + break; + + case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired: + log_i("Commissioning failed, fail safe timer expired"); + break; + + case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted: + log_i("Commissioning session started"); + break; + + case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped: + log_i("Commissioning session stopped"); + break; + + case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened: + log_i("Commissioning window opened"); + break; + + case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed: + log_i("Commissioning window closed"); + break; + + case chip::DeviceLayer::DeviceEventType::kFabricRemoved: + { + log_i("Fabric removed successfully"); + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + chip::CommissioningWindowManager & commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager(); + constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(k_timeout_seconds); + if (!commissionMgr.IsCommissioningWindowOpen()) + { + /* After removing last fabric, this example does not remove the Wi-Fi credentials + * and still has IP connectivity so, only advertising on DNS-SD. + */ + CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(kTimeoutSeconds, + chip::CommissioningWindowAdvertisement::kDnssdOnly); + if (err != CHIP_NO_ERROR) + { + log_e("Failed to open commissioning window, err:%" CHIP_ERROR_FORMAT, err.Format()); + } + } + } + break; + } + + case chip::DeviceLayer::DeviceEventType::kFabricWillBeRemoved: + log_i("Fabric will be removed"); + break; + + case chip::DeviceLayer::DeviceEventType::kFabricUpdated: + log_i("Fabric is updated"); + break; + + case chip::DeviceLayer::DeviceEventType::kFabricCommitted: + log_i("Fabric is committed"); + break; + + case chip::DeviceLayer::DeviceEventType::kBLEDeinitialized: + log_i("BLE deinitialized and memory reclaimed"); + break; + + default: + break; + } +} + +static uint32_t button_time_stamp = 0; +static void button_driver_down_cb() +{ + button_time_stamp = millis(); +} + + +static void button_driver_up_cb() +{ + uint32_t time_diff = millis() - button_time_stamp; + // Factory reset is triggered if the button is pressed for more than 3 seconds + if (time_diff > 3000) { + log_i("Factory reset triggered. Light will retored to factory settings."); + esp_matter::factory_reset(); + return; + } + + // Toggle button is pressed - toggle the light + log_i("Toggle button pressed"); + uint16_t endpoint_id = light_endpoint_id; + uint32_t cluster_id = OnOff::Id; + uint32_t attribute_id = OnOff::Attributes::OnOff::Id; + + node_t *node = node::get(); + endpoint_t *endpoint = endpoint::get(node, endpoint_id); + cluster_t *cluster = cluster::get(endpoint, cluster_id); + attribute_t *attribute = attribute::get(cluster, attribute_id); + + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + attribute::get_val(attribute, &val); + val.val.b = !val.val.b; + attribute::update(endpoint_id, cluster_id, attribute_id, &val); +} + +esp_err_t matter_light_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id, + uint32_t attribute_id, esp_matter_attr_val_t *val) +{ + esp_err_t err = ESP_OK; + if (endpoint_id == light_endpoint_id) { + void *led = (void *)driver_handle; + if (cluster_id == OnOff::Id) { + if (attribute_id == OnOff::Attributes::OnOff::Id) { + err = light_accessory_set_power(led, val->val.b); + } + } else if (cluster_id == LevelControl::Id) { + if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) { + err = light_accessory_set_brightness(led, val->val.u8); + } + } else if (cluster_id == ColorControl::Id) { + if (attribute_id == ColorControl::Attributes::CurrentHue::Id) { + err = light_accessory_set_hue(led, val->val.u8); + } else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) { + err = light_accessory_set_saturation(led, val->val.u8); + } else if (attribute_id == ColorControl::Attributes::ColorTemperatureMireds::Id) { + err = light_accessory_set_temperature(led, val->val.u16); + } + } + } + return err; +} + +esp_err_t matter_light_set_defaults(uint16_t endpoint_id) +{ + esp_err_t err = ESP_OK; + + void *led = endpoint::get_priv_data(endpoint_id); + node_t *node = node::get(); + endpoint_t *endpoint = endpoint::get(node, endpoint_id); + cluster_t *cluster = NULL; + attribute_t *attribute = NULL; + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + + /* Setting brightness */ + cluster = cluster::get(endpoint, LevelControl::Id); + attribute = attribute::get(cluster, LevelControl::Attributes::CurrentLevel::Id); + attribute::get_val(attribute, &val); + err |= light_accessory_set_brightness(led, val.val.u8); + + /* Setting color */ + cluster = cluster::get(endpoint, ColorControl::Id); + attribute = attribute::get(cluster, ColorControl::Attributes::ColorMode::Id); + attribute::get_val(attribute, &val); + if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kCurrentHueAndCurrentSaturation) { + /* Setting hue */ + attribute = attribute::get(cluster, ColorControl::Attributes::CurrentHue::Id); + attribute::get_val(attribute, &val); + err |= light_accessory_set_hue(led, val.val.u8); + /* Setting saturation */ + attribute = attribute::get(cluster, ColorControl::Attributes::CurrentSaturation::Id); + attribute::get_val(attribute, &val); + err |= light_accessory_set_saturation(led, val.val.u8); + } else if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kColorTemperature) { + /* Setting temperature */ + attribute = attribute::get(cluster, ColorControl::Attributes::ColorTemperatureMireds::Id); + attribute::get_val(attribute, &val); + err |= light_accessory_set_temperature(led, val.val.u16); + } else { + log_e("Color mode not supported"); + } + + /* Setting power */ + cluster = cluster::get(endpoint, OnOff::Id); + attribute = attribute::get(cluster, OnOff::Attributes::OnOff::Id); + attribute::get_val(attribute, &val); + err |= light_accessory_set_power(led, val.val.b); + + return err; +} + +void button_driver_init() +{ + /* Initialize button */ + uint8_t pin = 0; // set your board button pin here + pinMode(pin, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(pin), button_driver_down_cb, FALLING); // pressed + attachInterrupt(digitalPinToInterrupt(pin), button_driver_up_cb, RISING); // released +} + +// This callback is called for every attribute update. The callback implementation shall +// handle the desired attributes and return an appropriate error code. If the attribute +// is not of your interest, please do not return an error code and strictly return ESP_OK. +static esp_err_t app_attribute_update_cb(attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id, + uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data) +{ + esp_err_t err = ESP_OK; + + if (type == PRE_UPDATE) { + /* Driver update */ + app_driver_handle_t driver_handle = (app_driver_handle_t)priv_data; + err = matter_light_attribute_update(driver_handle, endpoint_id, cluster_id, attribute_id, val); + } + + return err; +} + +// This callback is invoked when clients interact with the Identify Cluster. +// In the callback implementation, an endpoint can identify itself. (e.g., by flashing an LED or light). +static esp_err_t app_identification_cb(identification::callback_type_t type, uint16_t endpoint_id, uint8_t effect_id, + uint8_t effect_variant, void *priv_data) +{ + log_i("Identification callback: type: %u, effect: %u, variant: %u", type, effect_id, effect_variant); + return ESP_OK; +} + +void setup() +{ + esp_err_t err = ESP_OK; + + /* Initialize the ESP NVS layer */ + //nvs_flash_init(); + + /* Initialize driver */ + app_driver_handle_t light_handle = light_accessory_init(); + button_driver_init(); + + /* Create a Matter node and add the mandatory Root Node device type on endpoint 0 */ + node::config_t node_config; + + // node handle can be used to add/modify other endpoints. + node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb); + if (node == nullptr) { + log_e("Failed to create Matter node"); + abort(); + } + + extended_color_light::config_t light_config; + light_config.on_off.on_off = DEFAULT_POWER; + light_config.on_off.lighting.start_up_on_off = nullptr; + light_config.level_control.current_level = DEFAULT_BRIGHTNESS; + light_config.level_control.lighting.start_up_current_level = DEFAULT_BRIGHTNESS; + light_config.color_control.color_mode = (uint8_t)ColorControl::ColorMode::kColorTemperature; + light_config.color_control.enhanced_color_mode = (uint8_t)ColorControl::ColorMode::kColorTemperature; + light_config.color_control.color_temperature.startup_color_temperature_mireds = nullptr; + + // endpoint handles can be used to add/modify clusters. + endpoint_t *endpoint = extended_color_light::create(node, &light_config, ENDPOINT_FLAG_NONE, light_handle); + if (endpoint == nullptr) { + log_e("Failed to create extended color light endpoint"); + abort(); + } + + light_endpoint_id = endpoint::get_id(endpoint); + log_i("Light created with endpoint_id %d", light_endpoint_id); + + /* Mark deferred persistence for some attributes that might be changed rapidly */ + cluster_t *level_control_cluster = cluster::get(endpoint, LevelControl::Id); + attribute_t *current_level_attribute = attribute::get(level_control_cluster, LevelControl::Attributes::CurrentLevel::Id); + attribute::set_deferred_persistence(current_level_attribute); + + cluster_t *color_control_cluster = cluster::get(endpoint, ColorControl::Id); + attribute_t *current_x_attribute = attribute::get(color_control_cluster, ColorControl::Attributes::CurrentX::Id); + attribute::set_deferred_persistence(current_x_attribute); + attribute_t *current_y_attribute = attribute::get(color_control_cluster, ColorControl::Attributes::CurrentY::Id); + attribute::set_deferred_persistence(current_y_attribute); + attribute_t *color_temp_attribute = attribute::get(color_control_cluster, ColorControl::Attributes::ColorTemperatureMireds::Id); + attribute::set_deferred_persistence(color_temp_attribute); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + /* Set OpenThread platform config */ + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + set_openthread_platform_config(&config); +#endif + + /* Matter start */ + err = esp_matter::start(app_event_cb); + if (err != ESP_OK) { + log_e("Failed to start Matter, err:%d", err); + abort(); + } + + /* Starting driver with default values */ + matter_light_set_defaults(light_endpoint_id); + +#if CONFIG_ENABLE_ENCRYPTED_OTA + err = esp_matter_ota_requestor_encrypted_init(s_decryption_key, s_decryption_key_len); + if (err != ESP_OK) { + log_e("Failed to initialized the encrypted OTA, err: %d", err); + abort(); + } +#endif // CONFIG_ENABLE_ENCRYPTED_OTA + +#if CONFIG_ENABLE_CHIP_SHELL + esp_matter::console::diagnostics_register_commands(); + esp_matter::console::wifi_register_commands(); +#if CONFIG_OPENTHREAD_CLI + esp_matter::console::otcli_register_commands(); +#endif + esp_matter::console::init(); +#endif +} + +void loop() { + delay(1000); +} diff --git a/examples/espidf-arduino-matter-light/partitions.csv b/examples/espidf-arduino-matter-light/partitions.csv new file mode 100644 index 0000000..f0992fa --- /dev/null +++ b/examples/espidf-arduino-matter-light/partitions.csv @@ -0,0 +1,9 @@ +# Name, Type, SubType, Offset, Size, Flags +esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted +nvs, data, nvs, 0x10000, 0xC000, +nvs_keys, data, nvs_keys,, 0x1000, encrypted +otadata, data, ota, , 0x2000 +phy_init, data, phy, , 0x1000, +ota_0, app, ota_0, 0x20000, 0x1E0000, +ota_1, app, ota_1, 0x200000, 0x1E0000, +fctry, data, nvs, 0x3E0000, 0x6000 diff --git a/examples/espidf-arduino-matter-light/platformio.ini b/examples/espidf-arduino-matter-light/platformio.ini new file mode 100644 index 0000000..0a46669 --- /dev/null +++ b/examples/espidf-arduino-matter-light/platformio.ini @@ -0,0 +1,26 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html +[platformio] +src_dir = main + +[env] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino, espidf +board_build.partitions = partitions.csv +monitor_speed = 115200 + + +[env:esp32s3] +board = esp32-s3-devkitc-1 +board_build.embed_txtfiles = + managed_components/espressif__esp_insights/server_certs/https_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt + managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt diff --git a/examples/espidf-arduino-matter-light/sdkconfig.defaults b/examples/espidf-arduino-matter-light/sdkconfig.defaults new file mode 100644 index 0000000..517a05a --- /dev/null +++ b/examples/espidf-arduino-matter-light/sdkconfig.defaults @@ -0,0 +1,66 @@ +# Arduino Settings +CONFIG_FREERTOS_HZ=1000 +CONFIG_AUTOSTART_ARDUINO=y + +# Log Levels +# Boot Messages - Log level +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y +# Arduino Log Level +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE=y +# IDF Log Level +CONFIG_LOG_DEFAULT_LEVEL_WARN=y + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +#disable BT connection reattempt +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +#enable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0xC000 + +# Disable chip shell +CONFIG_ENABLE_CHIP_SHELL=n + +#enable lwIP route hooks +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y + +# Button +CONFIG_BUTTON_PERIOD_TIME_MS=20 +CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000 + +# disable softap by default +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n + +# Disable DS Peripheral +CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + +# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1) +# unique local addresses for fabrics(MAX_FABRIC), a link local address(1) +CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 + + +# ESP32-S3-DevKitC-1 Settings +# Buttons +CONFIG_BSP_BUTTONS_NUM=1 +CONFIG_BSP_BUTTON_1_TYPE_GPIO=y +CONFIG_BSP_BUTTON_1_GPIO=0 +CONFIG_BSP_BUTTON_1_LEVEL=0 +# LEDs +CONFIG_BSP_LEDS_NUM=1 +CONFIG_BSP_LED_TYPE_RGB=y +CONFIG_BSP_LED_RGB_GPIO=48 +CONFIG_BSP_LED_RGB_BACKEND_RMT=y \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/test/README b/examples/espidf-arduino-matter-light/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/examples/espidf-arduino-matter-light/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html From 8c21dfa5b39fad5f7822ace34dae3002fa7596df Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:06:16 +0200 Subject: [PATCH 026/175] fix used platform --- examples/espidf-arduino-matter-light/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/espidf-arduino-matter-light/platformio.ini b/examples/espidf-arduino-matter-light/platformio.ini index 0a46669..25874c6 100644 --- a/examples/espidf-arduino-matter-light/platformio.ini +++ b/examples/espidf-arduino-matter-light/platformio.ini @@ -11,7 +11,7 @@ src_dir = main [env] -platform = https://github.com/pioarduino/platform-espressif32.git#develop +platform = espressif32 framework = arduino, espidf board_build.partitions = partitions.csv monitor_speed = 115200 From 04b83e3498ed20e2b436671af1598f33a425878d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 14 Sep 2024 17:22:35 +0200 Subject: [PATCH 027/175] prepare LP ULP support --- builder/frameworks/ulp.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index 7933bd9..6c49c9e 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -81,6 +81,15 @@ def get_component_includes(target_config): def generate_ulp_config(target_config): def _generate_ulp_configuration_action(env, target, source): riscv_ulp_enabled = sdk_config.get("ULP_COPROC_TYPE_RISCV", False) + lp_core_ulp_enabled = sdk_config.get("ULP_COPROC_TYPE_LP_CORE", False) + + if lp_core_ulp_enabled == False: + ulp_toolchain = "toolchain-%sulp%s.cmake"% ( + "" if riscv_ulp_enabled else idf_variant + "-", + "-riscv" if riscv_ulp_enabled else "", + ) + else: + ulp_toolchain = "toolchain-lp-core-riscv" cmd = ( os.path.join(platform.get_package_dir("tool-cmake"), "bin", "cmake"), @@ -91,11 +100,7 @@ def generate_ulp_config(target_config): "components", "ulp", "cmake", - "toolchain-%sulp%s.cmake" - % ( - "" if riscv_ulp_enabled else idf_variant + "-", - "-riscv" if riscv_ulp_enabled else "", - ), + ulp_toolchain, ), "-DULP_S_SOURCES=%s" % ";".join([fs.to_unix_path(s.get_abspath()) for s in source]), "-DULP_APP_NAME=ulp_main", From e8fef0a6c7ece79e222f09180fbae5dd00ebbe80 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 16 Sep 2024 20:11:32 +0200 Subject: [PATCH 028/175] enable bootloader components build --- builder/frameworks/espidf.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index cfabb28..6c55774 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -252,13 +252,11 @@ def populate_idf_env_vars(idf_env): os.path.dirname(get_python_exe()), ] - if mcu not in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): - additional_packages.append( - os.path.join(platform.get_package_dir("toolchain-esp32ulp"), "bin"), - ) +# if mcu in ("esp32", "esp32s2", "esp32s3"): +# additional_packages.append( +# os.path.join(platform.get_package_dir("toolchain-esp32ulp"), "bin"), +# ) -# if IS_WINDOWS: -# additional_packages.append(platform.get_package_dir("tool-mconf")) idf_env["PATH"] = os.pathsep.join(additional_packages + [idf_env["PATH"]]) @@ -875,6 +873,7 @@ def build_bootloader(sdk_config): "-DPYTHON=" + get_python_exe(), "-DIDF_PATH=" + FRAMEWORK_DIR, "-DSDKCONFIG=" + SDKCONFIG_PATH, + "-DPROJECT_SOURCE_DIR=" + PROJECT_DIR, "-DLEGACY_INCLUDE_COMMON_HEADERS=", "-DEXTRA_COMPONENT_DIRS=" + os.path.join(FRAMEWORK_DIR, "components", "bootloader"), @@ -1787,8 +1786,8 @@ env["BUILDERS"]["ElfToBin"].action = action # ulp_dir = os.path.join(PROJECT_DIR, "ulp") -if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): - env.SConscript("ulp.py", exports="env sdk_config project_config idf_variant") +if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32h2"): + env.SConscript("ulp.py", exports="env sdk_config project_config app_includes idf_variant") # # Process OTA partition and image From 02b4fe97a5d4ea44ed4edc3cad91980b79618a9e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 16 Sep 2024 20:39:23 +0200 Subject: [PATCH 029/175] ULP LP support --- builder/frameworks/ulp.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index 6c49c9e..7965df1 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -21,7 +21,7 @@ from platformio.proc import where_is_program, exec_command from SCons.Script import Import -Import("env sdk_config project_config idf_variant") +Import("env sdk_config project_config app_includes idf_variant") ulp_env = env.Clone() platform = ulp_env.PioPlatform() @@ -37,22 +37,24 @@ def prepare_ulp_env_vars(env): toolchain_path = platform.get_package_dir( "toolchain-xtensa-esp-elf" + if idf_variant not in ("esp32c6", "esp32p4") + else "toolchain-riscv32-esp" + ) + + toolchain_path_ulp = platform.get_package_dir( + "toolchain-esp32ulp" + if sdk_config.get("ULP_COPROC_TYPE_FSM", False) + else "" ) additional_packages = [ toolchain_path, - os.path.join( - platform.get_package_dir("toolchain-esp32ulp"), - "bin", - ), + toolchain_path_ulp, platform.get_package_dir("tool-ninja"), os.path.join(platform.get_package_dir("tool-cmake"), "bin"), os.path.dirname(where_is_program("python")), ] -# if "windows" in get_systype(): -# additional_packages.append(platform.get_package_dir("tool-mconf")) - for package in additional_packages: ulp_env.PrependENVPath("PATH", package) @@ -89,7 +91,11 @@ def generate_ulp_config(target_config): "-riscv" if riscv_ulp_enabled else "", ) else: - ulp_toolchain = "toolchain-lp-core-riscv" + ulp_toolchain = "toolchain-lp-core-riscv.cmake" + + comp_includes = ";".join(get_component_includes(target_config)) + plain_includes = ";".join(app_includes["plain_includes"]) + comp_includes = comp_includes + plain_includes cmd = ( os.path.join(platform.get_package_dir("tool-cmake"), "bin", "cmake"), @@ -105,7 +111,7 @@ def generate_ulp_config(target_config): "-DULP_S_SOURCES=%s" % ";".join([fs.to_unix_path(s.get_abspath()) for s in source]), "-DULP_APP_NAME=ulp_main", "-DCOMPONENT_DIR=" + os.path.join(ulp_env.subst("$PROJECT_DIR"), "ulp"), - "-DCOMPONENT_INCLUDES=%s" % ";".join(get_component_includes(target_config)), + "-DCOMPONENT_INCLUDES=" + comp_includes, "-DIDF_TARGET=%s" % idf_variant, "-DIDF_PATH=" + fs.to_unix_path(FRAMEWORK_DIR), "-DSDKCONFIG_HEADER=" + os.path.join(BUILD_DIR, "config", "sdkconfig.h"), From b1bc128119b5fdbe02268ba6f22e4c5c23d38dd0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:00:58 +0200 Subject: [PATCH 030/175] add missing P4 --- builder/frameworks/_embed_files.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/frameworks/_embed_files.py b/builder/frameworks/_embed_files.py index caa12c4..d8d9a35 100644 --- a/builder/frameworks/_embed_files.py +++ b/builder/frameworks/_embed_files.py @@ -110,14 +110,14 @@ env.Append( " ".join( [ "riscv32-esp-elf-objcopy" - if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2") + if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2","esp32p4") else "xtensa-%s-elf-objcopy" % mcu, "--input-target", "binary", "--output-target", - "elf32-littleriscv" if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2") else "elf32-xtensa-le", + "elf32-littleriscv" if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2","esp32p4") else "elf32-xtensa-le", "--binary-architecture", - "riscv" if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2") else "xtensa", + "riscv" if mcu in ("esp32c2","esp32c3","esp32c6","esp32h2","esp32p4") else "xtensa", "--rename-section", ".data=.rodata.embedded", "$SOURCE", From 29b02a9976333393f60043365255028e7a174855 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:07:42 +0200 Subject: [PATCH 031/175] add P4 --- builder/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/main.py b/builder/main.py index 07a6bb0..32ea2c9 100644 --- a/builder/main.py +++ b/builder/main.py @@ -232,7 +232,7 @@ board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") toolchain_arch = "xtensa-%s" % mcu filesystem = board.get("build.filesystem", "spiffs") -if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2"): +if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): toolchain_arch = "riscv32-esp" if "INTEGRATION_EXTRA_DATA" not in env: @@ -253,7 +253,7 @@ env.Replace( GDB=join( platform.get_package_dir( "tool-riscv32-esp-elf-gdb" - if mcu in ("esp32c2", "esp32c3", "esp32c6") + if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4") else "tool-xtensa-esp-elf-gdb" ) or "", From 00f997773f88951cb48b52bc7a7b34865dfed56f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:28:33 +0200 Subject: [PATCH 032/175] change some if checks --- builder/frameworks/espidf.py | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 6c55774..fe3c0dd 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -69,9 +69,9 @@ IDF5 = ( IDF_ENV_VERSION = "1.0.0" FRAMEWORK_DIR = platform.get_package_dir("framework-espidf") TOOLCHAIN_DIR = platform.get_package_dir( - "toolchain-riscv32-esp" - if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4") - else "toolchain-xtensa-esp-elf" + "toolchain-xtensa-esp-elf" + if mcu in ("esp32", "esp32s2", "esp32s3") + else "toolchain-riscv32-esp" ) @@ -252,12 +252,6 @@ def populate_idf_env_vars(idf_env): os.path.dirname(get_python_exe()), ] -# if mcu in ("esp32", "esp32s2", "esp32s3"): -# additional_packages.append( -# os.path.join(platform.get_package_dir("toolchain-esp32ulp"), "bin"), -# ) - - idf_env["PATH"] = os.pathsep.join(additional_packages + [idf_env["PATH"]]) # Some users reported that the `IDF_TOOLS_PATH` var can seep into the @@ -509,7 +503,7 @@ def extract_linker_script_fragments_backup(framework_components_dir, sdk_config) sys.stderr.write("Error: Failed to extract paths to linker script fragments\n") env.Exit(1) - if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4"): + if mcu not in ("esp32", "esp32s2", "esp32s3"): result.append(os.path.join(framework_components_dir, "riscv", "linker.lf")) # Add extra linker fragments @@ -1300,17 +1294,6 @@ def install_python_deps(): ) ) -# # A special "esp-windows-curses" python package is required on Windows -# # for Menuconfig on IDF <5 -# if not IDF5 and "esp-windows-curses" not in installed_packages: -# env.Execute( -# env.VerboseAction( -# '"%s" -m pip install "file://%s/tools/kconfig_new/esp-windows-curses"' -# % (python_exe_path, FRAMEWORK_DIR), -# "Installing windows-curses package", -# ) -# ) - def get_idf_venv_dir(): # The name of the IDF venv contains the IDF version to avoid possible conflicts and @@ -1675,7 +1658,7 @@ env.Prepend( ( board.get( "upload.bootloader_offset", - "0x0" if mcu in ["esp32c2", "esp32c3", "esp32c6", "esp32s3", "esp32h2"] else ("0x2000" if mcu in ["esp32p4"] else "0x1000"), + "0x1000" if mcu in ["esp32", "esp32s2"] else ("0x2000" if mcu in ["esp32p4"] else "0x0"), ), os.path.join("$BUILD_DIR", "bootloader.bin"), ), From d00384edab7b36b14b0cc124545a0d0bc9b2c3b4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:15:10 +0200 Subject: [PATCH 033/175] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 81434d1..e03df55 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Configure a platform option in [platformio.ini](https://docs.platformio.org/page/projectconf.html) file: ### Stable version -espressif Arduino 3.0.4 and IDF 5.1.4 +espressif Arduino 3.0.4 and IDF 5.1.4+ See `platform` [documentation](https://docs.platformio.org/en/latest/projectconf/sections/env/options/platform/platform.html#projectconf-env-platform) for details. @@ -47,7 +47,7 @@ board = ... ``` ### Bleeding edged development version -based on devel branch Arduino 3.1.0 and IDF 5.3.0 +based on devel branch Arduino 3.1.0 and IDF 5.3.1+ ```ini [env:development] From b68c01d16136eba1fa943936776f55665e385c5d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:37:12 +0200 Subject: [PATCH 034/175] remove wrong left over code --- builder/main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/builder/main.py b/builder/main.py index 32ea2c9..bf2f961 100644 --- a/builder/main.py +++ b/builder/main.py @@ -256,9 +256,6 @@ env.Replace( if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4") else "tool-xtensa-esp-elf-gdb" ) - or "", - "bin", - "%s-elf-gdb" % toolchain_arch, ), OBJCOPY=join(platform.get_package_dir("tool-esptoolpy") or "", "esptool.py"), RANLIB="%s-elf-gcc-ranlib" % toolchain_arch, From f380fbcb3e77506b751ccbdab9291452969a2f86 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:13:36 +0200 Subject: [PATCH 035/175] add ULP LP example / update Matter example --- .github/workflows/examples.yml | 1 + .../espidf-arduino-matter-light/README.md | 71 ++- .../main/Kconfig.projbuild | 102 ++++ .../main/builtinLED.cpp | 498 +++++++++--------- .../main/builtinLED.h | 150 +++--- .../main/matter_accessory_driver.cpp | 6 - .../main/matter_accessory_driver.h | 75 ++- .../main/matter_light.cpp | 148 ++++-- .../partitions.csv | 1 + .../platformio.ini | 2 + .../sdkconfig.defaults.c6_thread | 80 +++ .../sdkconfig.defaults.esp32c3 | 64 +++ .../sdkconfig.defaults.esp32c6 | 79 +++ .../sdkconfig.defaults.esp32s3 | 64 +++ examples/espidf-ulp-lp/CMakeLists.txt | 4 + examples/espidf-ulp-lp/README.md | 51 ++ examples/espidf-ulp-lp/platformio.ini | 13 + examples/espidf-ulp-lp/pytest_lp_core_pcnt.py | 30 ++ examples/espidf-ulp-lp/sdkconfig.defaults | 13 + examples/espidf-ulp-lp/src/CMakeLists.txt | 23 + examples/espidf-ulp-lp/src/Kconfig.projbuild | 20 + .../src/lp_core_pulse_counter_example_main.c | 85 +++ examples/espidf-ulp-lp/ulp/main.c | 64 +++ 23 files changed, 1232 insertions(+), 412 deletions(-) create mode 100644 examples/espidf-arduino-matter-light/main/Kconfig.projbuild create mode 100644 examples/espidf-arduino-matter-light/sdkconfig.defaults.c6_thread create mode 100644 examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c3 create mode 100644 examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c6 create mode 100644 examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32s3 create mode 100644 examples/espidf-ulp-lp/CMakeLists.txt create mode 100644 examples/espidf-ulp-lp/README.md create mode 100644 examples/espidf-ulp-lp/platformio.ini create mode 100644 examples/espidf-ulp-lp/pytest_lp_core_pcnt.py create mode 100644 examples/espidf-ulp-lp/sdkconfig.defaults create mode 100644 examples/espidf-ulp-lp/src/CMakeLists.txt create mode 100644 examples/espidf-ulp-lp/src/Kconfig.projbuild create mode 100644 examples/espidf-ulp-lp/src/lp_core_pulse_counter_example_main.c create mode 100644 examples/espidf-ulp-lp/ulp/main.c diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 0ed9246..7336fd3 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -32,6 +32,7 @@ jobs: - "examples/espidf-storage-sdcard" - "examples/espidf-ulp" - "examples/espidf-ulp-riscv" + - "espidf-ulp-lp" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/examples/espidf-arduino-matter-light/README.md b/examples/espidf-arduino-matter-light/README.md index fd3f77f..7d87688 100644 --- a/examples/espidf-arduino-matter-light/README.md +++ b/examples/espidf-arduino-matter-light/README.md @@ -1,3 +1,68 @@ -## Arduino/IDF Matter Light example - -The needed Matter component is added via the IDF component manager -> `idf_component.yml`. +| Supported Targets | ESP32-S3 | ESP32-C3 | ESP32-C6 | +| ----------------- | -------- | -------- | -------- | + + +# Managed Component Light + +This example is configured by default to work with the ESP32-S3, which has the RGB LED GPIO set as pin 48 and the BOOT button on GPIO 0. + +This example creates a Color Temperature Light device using the esp_matter component downloaded from the [Espressif Component Registry](https://components.espressif.com/) instead of an extra component locally, so the example can work without setting up the esp-matter environment. + +See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware. + +The code is based on the Arduino API and uses Arduino as an IDF Component. + +## How to use it + +Once the device runs for the first time, it must be commissioned to the Matter Fabric of the available Matter Environment. +Possible Matter Environments are: +- Amazon Alexa +- Google Home Assistant (*) +- Apple Home +- Open Source Home Assistant + +(*) Google Home Assistant requires the user to set up a Matter Light using the [Google Home Developer Console](https://developers.home.google.com/codelabs/matter-device#2). It is necessary to create a Matter Light device with VID = 0xFFF1 and PID = 0x8000. Otherwise, the Light won't show up in the GHA APP. This action is necessary because the Firmware uses Testing credentials and Google requires the user to create the testing device before using it. + +There is no QR Code to be used when the Smartphone APP wants to add the Matter Device. +Please enter the code manually: `34970112332` + +The devboard has a built-in LED that will be used as the Matter Light. +The default setting of the code uses pin 48 for the ESP32-S3. +Please change it in `main/matter_accessory_driver.h` or in the `sdkconfig.defaults.` file. + +## LED Status and Factory Mode + +The WS2812b built-in LED will turn purple as soon as the device is flashed and runs for the first time. +The purple color indicates that the Matter Accessory has not been commissioned yet. +After using a Matter provider Smartphone APP to add a Matter device to your Home Application, it may turn orange to indicate that it has no WiFi connection. + +Once it connects to the WiFi network, the LED will turn white to indicate that Matter is working and the device is connected to the Matter Environment. +Please note that Matter over WiFi using an ESP32 device will connect to a 2.4GHz WiFi SSID, therefore the Commissioner APP Smartphone shall be connected to this SSID. + +The Matter and WiFi configuration will be stored in NVS to ensure that it will connect to the Matter Fabric and WiFi Network again once it is reset. + +The Matter Smartphone APP will control the light state (ON/OFF), temperature (Warm/Cold White), and brightness. + +## On Board Light toggle button + +The built-in BOOT button will toggle On/Off and replicate the new state to the Matter Environment, making it visible in the Matter Smartphone APP as well. + +## Returning to the Factory State + +Holding the BOOT button pressed for more than 10 seconds and then releasing it will erase all Matter and WiFi configuration, forcing it to reset to factory state. After that, the device needs to be commissioned again. Previous setups done in the Smartphone APP won't work again; therefore, the virtual device shall be removed from the APP. + +## Building the Application using WiFi and Matter + +Use ESP-IDF 5.1.4 from https://github.com/espressif/esp-idf/tree/release/v5.1 +This example has been tested with Arduino Core 3.0.4 + +There is a configuration file for these SoC: esp32s3, esp32c3, esp32c6. +Those are the tested devices that have a WS2812 RGB LED and can run BLE, WiFi and Matter. + +In case it is necessary to change the Button Pin or the REG LED Pin, please use the `menuconfig` and change the Menu Option `Light Matter Accessory` + +## Using OpenThread with Matter + +This is possible with the ESP32-C6. +It is neessasy to have a Thread Border Routed in the Matter Environment. Check you matter hardware provider. + diff --git a/examples/espidf-arduino-matter-light/main/Kconfig.projbuild b/examples/espidf-arduino-matter-light/main/Kconfig.projbuild new file mode 100644 index 0000000..50e8914 --- /dev/null +++ b/examples/espidf-arduino-matter-light/main/Kconfig.projbuild @@ -0,0 +1,102 @@ +menu "Light Matter Accessory" + menu "On Board Light ON/OFF Button" + config BUTTON_PIN + int + prompt "Button 1 GPIO" + default ENV_GPIO_BOOT_BUTTON + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button that will be used to turn on/off the Matter Light. It shall be connected to a push button. It can use the BOOT button of the development board. + endmenu + + + menu "LEDs" + config WS2812_PIN + int + prompt "WS2812 RGB LED GPIO" + default ENV_GPIO_RGB_LED + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for the Matter Light that will be driven by RMT. It shall be connected to one single WS2812 RGB LED. + endmenu + + # TARGET CONFIGURATION + if IDF_TARGET_ESP32C3 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 19 + # GPIOs 20/21 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_BOOT_BUTTON + int + default 9 + + config ENV_GPIO_RGB_LED + int + default 8 + endif + if IDF_TARGET_ESP32C6 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 30 + # GPIOs 16/17 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_BOOT_BUTTON + int + default 9 + + config ENV_GPIO_RGB_LED + int + default 8 + endif + if IDF_TARGET_ESP32S3 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 48 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_BOOT_BUTTON + int + default 0 + + config ENV_GPIO_RGB_LED + int + default 48 + endif + +endmenu diff --git a/examples/espidf-arduino-matter-light/main/builtinLED.cpp b/examples/espidf-arduino-matter-light/main/builtinLED.cpp index cb7135e..9f2695b 100644 --- a/examples/espidf-arduino-matter-light/main/builtinLED.cpp +++ b/examples/espidf-arduino-matter-light/main/builtinLED.cpp @@ -1,251 +1,247 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. - - This will implement the onboard WS2812b LED as a LED indicator - It can be used to indicate some state or status of the device - The LED can be controlled using RGB, HSV or color temperature, brightness - - In this example, the LED Indicator class is used as the Matter light accessory -*/ - -#include -#include "builtinLED.h" - -typedef struct { - uint16_t hue; - uint8_t saturation; -} HS_color_t; - -static const HS_color_t temperatureTable[] = { - {4, 100}, {8, 100}, {11, 100}, {14, 100}, {16, 100}, {18, 100}, {20, 100}, {22, 100}, {24, 100}, {25, 100}, - {27, 100}, {28, 100}, {30, 100}, {31, 100}, {31, 95}, {30, 89}, {30, 85}, {29, 80}, {29, 76}, {29, 73}, - {29, 69}, {28, 66}, {28, 63}, {28, 60}, {28, 57}, {28, 54}, {28, 52}, {27, 49}, {27, 47}, {27, 45}, - {27, 43}, {27, 41}, {27, 39}, {27, 37}, {27, 35}, {27, 33}, {27, 31}, {27, 30}, {27, 28}, {27, 26}, - {27, 25}, {27, 23}, {27, 22}, {27, 21}, {27, 19}, {27, 18}, {27, 17}, {27, 15}, {28, 14}, {28, 13}, - {28, 12}, {29, 10}, {29, 9}, {30, 8}, {31, 7}, {32, 6}, {34, 5}, {36, 4}, {41, 3}, {49, 2}, - {0, 0}, {294, 2}, {265, 3}, {251, 4}, {242, 5}, {237, 6}, {233, 7}, {231, 8}, {229, 9}, {228, 10}, - {227, 11}, {226, 11}, {226, 12}, {225, 13}, {225, 13}, {224, 14}, {224, 14}, {224, 15}, {224, 15}, {223, 16}, - {223, 16}, {223, 17}, {223, 17}, {223, 17}, {222, 18}, {222, 18}, {222, 19}, {222, 19}, {222, 19}, {222, 19}, - {222, 20}, {222, 20}, {222, 20}, {222, 21}, {222, 21} -}; - -/* step brightness table: gamma = 2.3 */ -static const uint8_t gamma_table[MAX_PROGRESS] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, - 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, - 26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, - 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 86, - 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, - 108, 110, 111, 112, 114, 115, 117, 118, 120, 121, 123, 124, 126, 128, 129, 131, - 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 149, 150, 152, 154, 156, 157, - 159, 161, 163, 164, 166, 168, 170, 172, 174, 175, 177, 179, 181, 183, 185, 187, - 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, - 221, 223, 226, 228, 230, 232, 234, 236, 239, 241, 243, 245, 248, 250, 252, 255, -}; - -BuiltInLED::BuiltInLED() { - pin_number = (uint8_t) -1; // no pin number - state = false; // LED is off - hsv_color.value = 0; // black color -} - -BuiltInLED::~BuiltInLED(){ - end(); -} - -led_indicator_color_hsv_t BuiltInLED::rgb2hsv(led_indicator_color_rgb_t rgb) { - led_indicator_color_hsv_t hsv; - uint8_t minRGB, maxRGB; - uint8_t delta; - - minRGB = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b); - maxRGB = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b); - hsv.value = 0; - hsv.v = maxRGB; - delta = maxRGB - minRGB; - - if (delta == 0) { - hsv.h = 0; - hsv.s = 0; - } else { - hsv.s = delta * 255 / maxRGB; - - if (rgb.r == maxRGB) { - hsv.h = (60 * (rgb.g - rgb.b) / delta + 360) % 360; - } else if (rgb.g == maxRGB) { - hsv.h = (60 * (rgb.b - rgb.r) / delta + 120); - } else { - hsv.h = (60 * (rgb.r - rgb.g) / delta + 240); - } - } - return hsv; -} - -led_indicator_color_rgb_t BuiltInLED::hsv2rgb(led_indicator_color_hsv_t hsv) { - led_indicator_color_rgb_t rgb; - uint8_t rgb_max = hsv.v; - uint8_t rgb_min = rgb_max * (255 - hsv.s) / 255.0f; - - uint8_t i = hsv.h / 60; - uint8_t diff = hsv.h % 60; - - // RGB adjustment amount by hue - uint8_t rgb_adj = (rgb_max - rgb_min) * diff / 60; - rgb.value = 0; - switch (i) { - case 0: - rgb.r = rgb_max; - rgb.g = rgb_min + rgb_adj; - rgb.b = rgb_min; - break; - case 1: - rgb.r = rgb_max - rgb_adj; - rgb.g = rgb_max; - rgb.b = rgb_min; - break; - case 2: - rgb.r = rgb_min; - rgb.g = rgb_max; - rgb.b = rgb_min + rgb_adj; - break; - case 3: - rgb.r = rgb_min; - rgb.g = rgb_max - rgb_adj; - rgb.b = rgb_max; - break; - case 4: - rgb.r = rgb_min + rgb_adj; - rgb.g = rgb_min; - rgb.b = rgb_max; - break; - default: - rgb.r = rgb_max; - rgb.g = rgb_min; - rgb.b = rgb_max - rgb_adj; - break; - } - - // gamma correction - rgb.r = gamma_table[rgb.r]; - rgb.g = gamma_table[rgb.g]; - rgb.b = gamma_table[rgb.b]; - return rgb; -} - -void BuiltInLED::begin(uint8_t pin){ - if (pin < NUM_DIGITAL_PINS) { - pin_number = pin; - write(); - } else { - log_e("Invalid pin (%d) number", pin); - } -} -void BuiltInLED::end(){ - state = false; - write(); - if (pin_number < NUM_DIGITAL_PINS) { - if (!rmtDeinit(pin_number)) { - log_e("Failed to deinitialize RMT"); - } - } -} - -void BuiltInLED::on(){ - state = true; -} - -void BuiltInLED::off(){ - state = false; -} - -void BuiltInLED::toggle(){ - state = !state; -} - -bool BuiltInLED::getState(){ - return state; -} - -bool BuiltInLED::write(){ - led_indicator_color_rgb_t rgb_color = getRGB(); - log_d("Writing to pin %d with state = %s", pin_number, state ? "ON" : "OFF"); - log_d("HSV: %d, %d, %d", hsv_color.h, hsv_color.s, hsv_color.v); - log_d("RGB: %d, %d, %d", rgb_color.r, rgb_color.g, rgb_color.b); - if(pin_number < NUM_DIGITAL_PINS){ - if (state) { - rgbLedWrite(pin_number, rgb_color.r, rgb_color.g, rgb_color.b); - } else { - rgbLedWrite(pin_number, 0, 0, 0); - } - return true; - } else { - log_e("Invalid pin (%d) number", pin_number); - return false; - } -} - -void BuiltInLED::setBrightness(uint8_t brightness){ - hsv_color.v = brightness; -} - -uint8_t BuiltInLED::getBrightness(){ - return hsv_color.v; -} - -void BuiltInLED::setHSV(led_indicator_color_hsv_t hsv){ - if (hsv.h > MAX_HUE) { - hsv.h = MAX_HUE; - } - hsv_color.value = hsv.value; -} - -led_indicator_color_hsv_t BuiltInLED::getHSV(){ - return hsv_color; -} - -void BuiltInLED::setRGB(led_indicator_color_rgb_t rgb_color){ - hsv_color = rgb2hsv(rgb_color); -} - -led_indicator_color_rgb_t BuiltInLED::getRGB(){ - return hsv2rgb(hsv_color); -} - -void BuiltInLED::setTemperature(uint32_t temperature){ - uint16_t hue; - uint8_t saturation; - - log_d("Requested Temperature: %ld", temperature); - //hsv_color.v = gamma_table[((temperature >> 25) & 0x7F)]; - temperature &= 0xFFFFFF; - if (temperature < 600) { - hue = 0; - saturation = 100; - } else { - if (temperature > 10000) { - hue = 222; - saturation = 21 + (temperature - 10000) * 41 / 990000; - } else { - temperature -= 600; - temperature /= 100; - hue = temperatureTable[temperature].hue; - saturation = temperatureTable[temperature].saturation; - } - } - saturation = (saturation * 255) / 100; - // brightness is not changed - hsv_color.h = hue; - hsv_color.s = saturation; - log_d("Calculated Temperature: %ld, Hue: %d, Saturation: %d, Brightness: %d", temperature, hue, saturation, hsv_color.v); -} - +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + This will implement the onboard WS2812b LED as a LED indicator + It can be used to indicate some state or status of the device + The LED can be controlled using RGB, HSV or color temperature, brightness + + In this example, the LED Indicator class is used as the Matter light accessory +*/ + +#include "builtinLED.h" + +typedef struct { + uint16_t hue; + uint8_t saturation; +} HS_color_t; + +static const HS_color_t temperatureTable[] = { + {4, 100}, {8, 100}, {11, 100}, {14, 100}, {16, 100}, {18, 100}, {20, 100}, {22, 100}, {24, 100}, {25, 100}, + {27, 100}, {28, 100}, {30, 100}, {31, 100}, {31, 95}, {30, 89}, {30, 85}, {29, 80}, {29, 76}, {29, 73}, + {29, 69}, {28, 66}, {28, 63}, {28, 60}, {28, 57}, {28, 54}, {28, 52}, {27, 49}, {27, 47}, {27, 45}, + {27, 43}, {27, 41}, {27, 39}, {27, 37}, {27, 35}, {27, 33}, {27, 31}, {27, 30}, {27, 28}, {27, 26}, + {27, 25}, {27, 23}, {27, 22}, {27, 21}, {27, 19}, {27, 18}, {27, 17}, {27, 15}, {28, 14}, {28, 13}, + {28, 12}, {29, 10}, {29, 9}, {30, 8}, {31, 7}, {32, 6}, {34, 5}, {36, 4}, {41, 3}, {49, 2}, + {0, 0}, {294, 2}, {265, 3}, {251, 4}, {242, 5}, {237, 6}, {233, 7}, {231, 8}, {229, 9}, {228, 10}, + {227, 11}, {226, 11}, {226, 12}, {225, 13}, {225, 13}, {224, 14}, {224, 14}, {224, 15}, {224, 15}, {223, 16}, + {223, 16}, {223, 17}, {223, 17}, {223, 17}, {222, 18}, {222, 18}, {222, 19}, {222, 19}, {222, 19}, {222, 19}, + {222, 20}, {222, 20}, {222, 20}, {222, 21}, {222, 21} +}; + +/* step brightness table: gamma = 2.3 */ +static const uint8_t gamma_table[MAX_PROGRESS] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, + 26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 86, + 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, + 108, 110, 111, 112, 114, 115, 117, 118, 120, 121, 123, 124, 126, 128, 129, 131, + 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 149, 150, 152, 154, 156, 157, + 159, 161, 163, 164, 166, 168, 170, 172, 174, 175, 177, 179, 181, 183, 185, 187, + 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, + 221, 223, 226, 228, 230, 232, 234, 236, 239, 241, 243, 245, 248, 250, 252, 255, +}; + +BuiltInLED::BuiltInLED() { + pin_number = (uint8_t) -1; // no pin number + state = false; // LED is off + hsv_color.value = 0; // black color +} + +BuiltInLED::~BuiltInLED(){ + end(); +} + +led_indicator_color_hsv_t BuiltInLED::rgb2hsv(led_indicator_color_rgb_t rgb) { + led_indicator_color_hsv_t hsv; + uint8_t minRGB, maxRGB; + uint8_t delta; + + minRGB = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b); + maxRGB = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b); + hsv.value = 0; + hsv.v = maxRGB; + delta = maxRGB - minRGB; + + if (delta == 0) { + hsv.h = 0; + hsv.s = 0; + } else { + hsv.s = delta * 255 / maxRGB; + + if (rgb.r == maxRGB) { + hsv.h = (60 * (rgb.g - rgb.b) / delta + 360) % 360; + } else if (rgb.g == maxRGB) { + hsv.h = (60 * (rgb.b - rgb.r) / delta + 120); + } else { + hsv.h = (60 * (rgb.r - rgb.g) / delta + 240); + } + } + return hsv; +} + +led_indicator_color_rgb_t BuiltInLED::hsv2rgb(led_indicator_color_hsv_t hsv) { + led_indicator_color_rgb_t rgb; + uint8_t rgb_max = hsv.v; + uint8_t rgb_min = rgb_max * (255 - hsv.s) / 255.0f; + + uint8_t i = hsv.h / 60; + uint8_t diff = hsv.h % 60; + + // RGB adjustment amount by hue + uint8_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + rgb.value = 0; + switch (i) { + case 0: + rgb.r = rgb_max; + rgb.g = rgb_min + rgb_adj; + rgb.b = rgb_min; + break; + case 1: + rgb.r = rgb_max - rgb_adj; + rgb.g = rgb_max; + rgb.b = rgb_min; + break; + case 2: + rgb.r = rgb_min; + rgb.g = rgb_max; + rgb.b = rgb_min + rgb_adj; + break; + case 3: + rgb.r = rgb_min; + rgb.g = rgb_max - rgb_adj; + rgb.b = rgb_max; + break; + case 4: + rgb.r = rgb_min + rgb_adj; + rgb.g = rgb_min; + rgb.b = rgb_max; + break; + default: + rgb.r = rgb_max; + rgb.g = rgb_min; + rgb.b = rgb_max - rgb_adj; + break; + } + + // gamma correction + rgb.r = gamma_table[rgb.r]; + rgb.g = gamma_table[rgb.g]; + rgb.b = gamma_table[rgb.b]; + return rgb; +} + +void BuiltInLED::begin(uint8_t pin){ + if (pin < NUM_DIGITAL_PINS) { + pin_number = pin; + log_i("Initializing pin %d", pin); + } else { + log_e("Invalid pin (%d) number", pin); + } +} +void BuiltInLED::end(){ + state = false; + write(); // turn off the LED + if (pin_number < NUM_DIGITAL_PINS) { + if (!rmtDeinit(pin_number)) { + log_e("Failed to deinitialize RMT"); + } + } +} + +void BuiltInLED::on(){ + state = true; +} + +void BuiltInLED::off(){ + state = false; +} + +void BuiltInLED::toggle(){ + state = !state; +} + +bool BuiltInLED::getState(){ + return state; +} + +bool BuiltInLED::write(){ + led_indicator_color_rgb_t rgb_color = getRGB(); + log_d("Writing to pin %d with state = %s", pin_number, state ? "ON" : "OFF"); + log_d("HSV: %d, %d, %d", hsv_color.h, hsv_color.s, hsv_color.v); + log_d("RGB: %d, %d, %d", rgb_color.r, rgb_color.g, rgb_color.b); + if(pin_number < NUM_DIGITAL_PINS){ + if (state) { + rgbLedWrite(pin_number, rgb_color.r, rgb_color.g, rgb_color.b); + } else { + rgbLedWrite(pin_number, 0, 0, 0); + } + return true; + } else { + log_e("Invalid pin (%d) number", pin_number); + return false; + } +} + +void BuiltInLED::setBrightness(uint8_t brightness){ + hsv_color.v = brightness; +} + +uint8_t BuiltInLED::getBrightness(){ + return hsv_color.v; +} + +void BuiltInLED::setHSV(led_indicator_color_hsv_t hsv){ + if (hsv.h > MAX_HUE) { + hsv.h = MAX_HUE; + } + hsv_color.value = hsv.value; +} + +led_indicator_color_hsv_t BuiltInLED::getHSV(){ + return hsv_color; +} + +void BuiltInLED::setRGB(led_indicator_color_rgb_t rgb_color){ + hsv_color = rgb2hsv(rgb_color); +} + +led_indicator_color_rgb_t BuiltInLED::getRGB(){ + return hsv2rgb(hsv_color); +} + +void BuiltInLED::setTemperature(uint32_t temperature){ + uint16_t hue; + uint8_t saturation; + + log_d("Requested Temperature: %ld", temperature); + //hsv_color.v = gamma_table[((temperature >> 25) & 0x7F)]; + temperature &= 0xFFFFFF; + if (temperature < 600) { + hue = 0; + saturation = 100; + } else { + if (temperature > 10000) { + hue = 222; + saturation = 21 + (temperature - 10000) * 41 / 990000; + } else { + temperature -= 600; + temperature /= 100; + hue = temperatureTable[temperature].hue; + saturation = temperatureTable[temperature].saturation; + } + } + saturation = (saturation * 255) / 100; + // brightness is not changed + hsv_color.h = hue; + hsv_color.s = saturation; + log_d("Calculated Temperature: %ld, Hue: %d, Saturation: %d, Brightness: %d", temperature, hue, saturation, hsv_color.v); +} \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/main/builtinLED.h b/examples/espidf-arduino-matter-light/main/builtinLED.h index 85fc171..7a2f2ec 100644 --- a/examples/espidf-arduino-matter-light/main/builtinLED.h +++ b/examples/espidf-arduino-matter-light/main/builtinLED.h @@ -1,76 +1,74 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. - - This will implement the onboard WS2812b LED as a LED indicator - It can be used to indicate some state or status of the device - The LED can be controlled using RGB, HSV or color temperature, brightness - - In this example, the BuiltInLED class is used as the Matter light accessory -*/ - -#pragma once - -#include - -#define MAX_HUE 360 -#define MAX_SATURATION 255 -#define MAX_BRIGHTNESS 255 -#define MAX_PROGRESS 256 - -typedef struct { - union { - struct { - uint32_t v: 8; /*!< Brightness/Value of the LED. 0-255 */ - uint32_t s: 8; /*!< Saturation of the LED. 0-255 */ - uint32_t h: 9; /*!< Hue of the LED. 0-360 */ - }; - uint32_t value; /*!< IHSV value of the LED. */ - }; -} led_indicator_color_hsv_t; - -typedef struct { - union { - struct { - uint32_t r: 8; /*!< Red component of the LED color. Range: 0-255. */ - uint32_t g: 8; /*!< Green component of the LED color. Range: 0-255. */ - uint32_t b: 8; /*!< Blue component of the LED color. Range: 0-255. */ - }; - uint32_t value; /*!< Combined RGB value of the LED color. */ - }; -} led_indicator_color_rgb_t; - -class BuiltInLED { -private: - uint8_t pin_number; - bool state; - led_indicator_color_hsv_t hsv_color; - -public: - BuiltInLED(); - ~BuiltInLED(); - - static led_indicator_color_hsv_t rgb2hsv(led_indicator_color_rgb_t rgb_value); - static led_indicator_color_rgb_t hsv2rgb(led_indicator_color_hsv_t hsv); - - void begin(uint8_t pin); - void end(); - - void on(); - void off(); - void toggle(); - bool getState(); - - bool write(); - - void setBrightness(uint8_t brightness); - uint8_t getBrightness(); - void setHSV(led_indicator_color_hsv_t hsv); - led_indicator_color_hsv_t getHSV(); - void setRGB(led_indicator_color_rgb_t color); - led_indicator_color_rgb_t getRGB(); - void setTemperature(uint32_t temperature); -}; +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + This will implement the onboard WS2812b LED as a LED indicator + It can be used to indicate some state or status of the device + The LED can be controlled using RGB, HSV or color temperature, brightness + + In this example, the BuiltInLED class is used as the Matter light accessory +*/ + +#pragma once + +#include + +#define MAX_HUE 360 +#define MAX_SATURATION 255 +#define MAX_BRIGHTNESS 255 +#define MAX_PROGRESS 256 + +typedef struct { + union { + struct { + uint32_t v: 8; /*!< Brightness/Value of the LED. 0-255 */ + uint32_t s: 8; /*!< Saturation of the LED. 0-255 */ + uint32_t h: 9; /*!< Hue of the LED. 0-360 */ + }; + uint32_t value; /*!< IHSV value of the LED. */ + }; +} led_indicator_color_hsv_t; + +typedef struct { + union { + struct { + uint32_t r: 8; /*!< Red component of the LED color. Range: 0-255. */ + uint32_t g: 8; /*!< Green component of the LED color. Range: 0-255. */ + uint32_t b: 8; /*!< Blue component of the LED color. Range: 0-255. */ + }; + uint32_t value; /*!< Combined RGB value of the LED color. */ + }; +} led_indicator_color_rgb_t; + +class BuiltInLED { +private: + uint8_t pin_number; + bool state; + led_indicator_color_hsv_t hsv_color; + +public: + BuiltInLED(); + ~BuiltInLED(); + + static led_indicator_color_hsv_t rgb2hsv(led_indicator_color_rgb_t rgb_value); + static led_indicator_color_rgb_t hsv2rgb(led_indicator_color_hsv_t hsv); + + void begin(uint8_t pin); + void end(); + + void on(); + void off(); + void toggle(); + bool getState(); + + bool write(); + + void setBrightness(uint8_t brightness); + uint8_t getBrightness(); + void setHSV(led_indicator_color_hsv_t hsv); + led_indicator_color_hsv_t getHSV(); + void setRGB(led_indicator_color_rgb_t color); + led_indicator_color_rgb_t getRGB(); + void setTemperature(uint32_t temperature); +}; \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp index 9fe2b16..8e3cc7e 100644 --- a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp +++ b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.cpp @@ -1,6 +1,5 @@ /* This example code is in the Public Domain (or CC0 licensed, at your option.) - Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -11,9 +10,6 @@ #include "builtinLED.h" #include "matter_accessory_driver.h" -// set your board WS2812b pin here (e.g. 48 is the default pin for the ESP32-S3 devkit) -#define WS2812_PIN 48 - /* Do any conversions/remapping for the actual value here */ esp_err_t light_accessory_set_power(void *led, uint8_t val) { @@ -95,7 +91,5 @@ app_driver_handle_t light_accessory_init() const uint8_t pin = WS2812_PIN; // set your board WS2812b pin here builtinLED.begin(pin); - builtinLED.setHSV({DEFAULT_HUE, DEFAULT_SATURATION, DEFAULT_BRIGHTNESS}); - builtinLED.write(); return (app_driver_handle_t) &builtinLED; } diff --git a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h index b3b6692..8d816c7 100644 --- a/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h +++ b/examples/espidf-arduino-matter-light/main/matter_accessory_driver.h @@ -1,28 +1,47 @@ -#include - -/** Standard max values (used for remapping attributes) */ -#define STANDARD_BRIGHTNESS 255 -#define STANDARD_HUE 360 -#define STANDARD_SATURATION 255 -#define STANDARD_TEMPERATURE_FACTOR 1000000 - -/** Matter max values (used for remapping attributes) */ -#define MATTER_BRIGHTNESS 254 -#define MATTER_HUE 254 -#define MATTER_SATURATION 254 -#define MATTER_TEMPERATURE_FACTOR 1000000 - -/** Default attribute values used during initialization */ -#define DEFAULT_POWER true -#define DEFAULT_BRIGHTNESS 64 -#define DEFAULT_HUE 128 -#define DEFAULT_SATURATION 254 - -typedef void *app_driver_handle_t; - -esp_err_t light_accessory_set_power(void *led, uint8_t val); -esp_err_t light_accessory_set_brightness(void *led, uint8_t val); -esp_err_t light_accessory_set_hue(void *led, uint8_t val); -esp_err_t light_accessory_set_saturation(void *led, uint8_t val); -esp_err_t light_accessory_set_temperature(void *led, uint16_t val); -app_driver_handle_t light_accessory_init(); +#include +#include + +// set your board WS2812b pin here (e.g. 48 is the default pin for the ESP32-S3 devkit) +#ifndef CONFIG_WS2812_PIN +#define WS2812_PIN 48 // ESP32-S3 DevKitC built-in LED +#else +#define WS2812_PIN CONFIG_WS2812_PIN // From sdkconfig.defaults. +#endif + +#ifndef RGB_BUILTIN +#define RGB_BUILTIN WS2812_PIN +#endif + +// Set your board button pin here (e.g. 0 is the default pin for the ESP32-S3 devkit) +#ifndef CONFIG_BUTTON_PIN +#define BUTTON_PIN 0 // ESP32-S3 DevKitC built-in button +#else +#define BUTTON_PIN CONFIG_BUTTON_PIN // From sdkconfig.defaults. +#endif + +/** Standard max values (used for remapping attributes) */ +#define STANDARD_BRIGHTNESS 255 +#define STANDARD_HUE 360 +#define STANDARD_SATURATION 255 +#define STANDARD_TEMPERATURE_FACTOR 1000000 + +/** Matter max values (used for remapping attributes) */ +#define MATTER_BRIGHTNESS 254 +#define MATTER_HUE 254 +#define MATTER_SATURATION 254 +#define MATTER_TEMPERATURE_FACTOR 1000000 + +/** Default attribute values used during initialization */ +#define DEFAULT_POWER true +#define DEFAULT_BRIGHTNESS 64 +#define DEFAULT_HUE 128 +#define DEFAULT_SATURATION 254 + +typedef void *app_driver_handle_t; + +esp_err_t light_accessory_set_power(void *led, uint8_t val); +esp_err_t light_accessory_set_brightness(void *led, uint8_t val); +esp_err_t light_accessory_set_hue(void *led, uint8_t val); +esp_err_t light_accessory_set_saturation(void *led, uint8_t val); +esp_err_t light_accessory_set_temperature(void *led, uint16_t val); +app_driver_handle_t light_accessory_init(); \ No newline at end of file diff --git a/examples/espidf-arduino-matter-light/main/matter_light.cpp b/examples/espidf-arduino-matter-light/main/matter_light.cpp index 76d5cfe..5f3898e 100644 --- a/examples/espidf-arduino-matter-light/main/matter_light.cpp +++ b/examples/espidf-arduino-matter-light/main/matter_light.cpp @@ -1,6 +1,5 @@ /* This example code is in the Public Domain (or CC0 licensed, at your option.) - Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -37,6 +36,9 @@ } #endif +// set your board button pin here +const uint8_t button_gpio = BUTTON_PIN; // GPIO BOOT Button + uint16_t light_endpoint_id = 0; using namespace esp_matter; @@ -54,11 +56,29 @@ static const char *s_decryption_key = decryption_key_start; static const uint16_t s_decryption_key_len = decryption_key_end - decryption_key_start; #endif // CONFIG_ENABLE_ENCRYPTED_OTA +bool isAccessoryCommissioned() { + return chip::Server::GetInstance().GetFabricTable().FabricCount() > 0; +} + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +bool isWifiConnected() { + return chip::DeviceLayer::ConnectivityMgr().IsWiFiStationConnected(); +} +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +bool isThreadConnected() { + return chip::DeviceLayer::ConnectivityMgr().IsThreadAttached(); +} +#endif + static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) { switch (event->Type) { case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged: - log_i("Interface IP Address changed"); + log_i("Interface %s Address changed", + event->InterfaceIpAddressChanged.Type == chip::DeviceLayer::InterfaceIpChangeType::kIpV4_Assigned ? + "IPv4" : "IPV6" ); break; case chip::DeviceLayer::DeviceEventType::kCommissioningComplete: @@ -129,40 +149,6 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) } } -static uint32_t button_time_stamp = 0; -static void button_driver_down_cb() -{ - button_time_stamp = millis(); -} - - -static void button_driver_up_cb() -{ - uint32_t time_diff = millis() - button_time_stamp; - // Factory reset is triggered if the button is pressed for more than 3 seconds - if (time_diff > 3000) { - log_i("Factory reset triggered. Light will retored to factory settings."); - esp_matter::factory_reset(); - return; - } - - // Toggle button is pressed - toggle the light - log_i("Toggle button pressed"); - uint16_t endpoint_id = light_endpoint_id; - uint32_t cluster_id = OnOff::Id; - uint32_t attribute_id = OnOff::Attributes::OnOff::Id; - - node_t *node = node::get(); - endpoint_t *endpoint = endpoint::get(node, endpoint_id); - cluster_t *cluster = cluster::get(endpoint, cluster_id); - attribute_t *attribute = attribute::get(cluster, attribute_id); - - esp_matter_attr_val_t val = esp_matter_invalid(NULL); - attribute::get_val(attribute, &val); - val.val.b = !val.val.b; - attribute::update(endpoint_id, cluster_id, attribute_id, &val); -} - esp_err_t matter_light_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) { @@ -241,10 +227,7 @@ esp_err_t matter_light_set_defaults(uint16_t endpoint_id) void button_driver_init() { /* Initialize button */ - uint8_t pin = 0; // set your board button pin here - pinMode(pin, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(pin), button_driver_down_cb, FALLING); // pressed - attachInterrupt(digitalPinToInterrupt(pin), button_driver_up_cb, RISING); // released + pinMode(button_gpio, INPUT_PULLUP); } // This callback is called for every attribute update. The callback implementation shall @@ -277,9 +260,6 @@ void setup() { esp_err_t err = ESP_OK; - /* Initialize the ESP NVS layer */ - //nvs_flash_init(); - /* Initialize driver */ app_driver_handle_t light_handle = light_accessory_init(); button_driver_init(); @@ -309,7 +289,7 @@ void setup() log_e("Failed to create extended color light endpoint"); abort(); } - + light_endpoint_id = endpoint::get_id(endpoint); log_i("Light created with endpoint_id %d", light_endpoint_id); @@ -343,9 +323,6 @@ void setup() abort(); } - /* Starting driver with default values */ - matter_light_set_defaults(light_endpoint_id); - #if CONFIG_ENABLE_ENCRYPTED_OTA err = esp_matter_ota_requestor_encrypted_init(s_decryption_key, s_decryption_key_len); if (err != ESP_OK) { @@ -365,5 +342,80 @@ void setup() } void loop() { - delay(1000); + static uint32_t button_time_stamp = 0; + static bool button_state = false; + static bool started = false; + + if(!isAccessoryCommissioned()) { + log_w("Accessory not commissioned yet. Waiting for commissioning."); +#ifdef RGB_BUILTIN + rgbLedWrite(RGB_BUILTIN, 48, 0, 20); // Purple indicates accessory not commissioned +#endif + delay(5000); + return; + } + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + if (!isWifiConnected()) { + log_w("Wi-Fi not connected yet. Waiting for connection."); +#ifdef RGB_BUILTIN + rgbLedWrite(RGB_BUILTIN, 48, 20, 0); // Orange indicates accessory not connected to Wi-Fi +#endif + delay(5000); + return; + } +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + if (!isThreadConnected()) { + log_w("Thread not connected yet. Waiting for connection."); +#ifdef RGB_BUILTIN + rgbLedWrite(RGB_BUILTIN, 0, 20, 48); // Blue indicates accessory not connected to Trhead +#endif + delay(5000); + return; + } +#endif + + // Once all network connections are established, the accessory is ready for use + // Run it only once + if (!started) { + log_i("Accessory is commissioned and connected to Wi-Fi. Ready for use."); + started = true; + // Starting driver with default values + matter_light_set_defaults(light_endpoint_id); + } + + // Check if the button is pressed and toggle the light right away + if (digitalRead(button_gpio) == LOW && !button_state) { + // deals with button debounce + button_time_stamp = millis(); // record the time while the button is pressed. + button_state = true; // pressed. + + // Toggle button is pressed - toggle the light + log_i("Toggle button pressed"); + + endpoint_t *endpoint = endpoint::get(node::get(), light_endpoint_id); + cluster_t *cluster = cluster::get(endpoint, OnOff::Id); + attribute_t *attribute = attribute::get(cluster, OnOff::Attributes::OnOff::Id); + + esp_matter_attr_val_t val = esp_matter_invalid(NULL); + attribute::get_val(attribute, &val); + val.val.b = !val.val.b; + attribute::update(light_endpoint_id, OnOff::Id, OnOff::Attributes::OnOff::Id, &val); + } + + // Check if the button is released and handle the factory reset + uint32_t time_diff = millis() - button_time_stamp; + if (button_state && time_diff > 100 && digitalRead(button_gpio) == HIGH) { + button_state = false; // released. It can be pressed again after 100ms debounce. + + // Factory reset is triggered if the button is pressed for more than 10 seconds + if (time_diff > 10000) { + log_i("Factory reset triggered. Light will retored to factory settings."); + esp_matter::factory_reset(); + } + } + + delay(50); // WDT is happier with a delay } diff --git a/examples/espidf-arduino-matter-light/partitions.csv b/examples/espidf-arduino-matter-light/partitions.csv index f0992fa..ffe5f24 100644 --- a/examples/espidf-arduino-matter-light/partitions.csv +++ b/examples/espidf-arduino-matter-light/partitions.csv @@ -1,4 +1,5 @@ # Name, Type, SubType, Offset, Size, Flags +# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted nvs, data, nvs, 0x10000, 0xC000, nvs_keys, data, nvs_keys,, 0x1000, encrypted diff --git a/examples/espidf-arduino-matter-light/platformio.ini b/examples/espidf-arduino-matter-light/platformio.ini index 25874c6..2434a84 100644 --- a/examples/espidf-arduino-matter-light/platformio.ini +++ b/examples/espidf-arduino-matter-light/platformio.ini @@ -7,6 +7,8 @@ ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html + + [platformio] src_dir = main diff --git a/examples/espidf-arduino-matter-light/sdkconfig.defaults.c6_thread b/examples/espidf-arduino-matter-light/sdkconfig.defaults.c6_thread new file mode 100644 index 0000000..389c72c --- /dev/null +++ b/examples/espidf-arduino-matter-light/sdkconfig.defaults.c6_thread @@ -0,0 +1,80 @@ +CONFIG_IDF_TARGET="esp32c6" + +# Arduino Settings +CONFIG_FREERTOS_HZ=1000 +CONFIG_AUTOSTART_ARDUINO=y + +# Log Levels +# Boot Messages - Log level +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y +# Arduino Log Level +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO=y +# IDF Log Level +CONFIG_LOG_DEFAULT_LEVEL_ERROR=y + +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +# libsodium +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y + +# NIMBLE +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_EXT_ADV=n +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n + +# FreeRTOS should use legacy API +CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y + +# Enable OpenThread +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_SRP_CLIENT=y +CONFIG_OPENTHREAD_DNS_CLIENT=y +CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n +CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y +CONFIG_OPENTHREAD_CLI=n + +# Disable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=n + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" + +# LwIP config for OpenThread +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_MULTICAST_PING=y + +# MDNS platform +CONFIG_USE_MINIMAL_MDNS=n +CONFIG_ENABLE_EXTENDED_DISCOVERY=y + +# Enable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=n + +# Disable STA and AP for ESP32C6 +CONFIG_ENABLE_WIFI_STATION=n +CONFIG_ENABLE_WIFI_AP=n + +# Enable chip shell +CONFIG_ENABLE_CHIP_SHELL=n + +# Disable persist subscriptions +CONFIG_ENABLE_PERSIST_SUBSCRIPTIONS=n + +# MRP configs +CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL_FOR_THREAD=5000 +CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL_FOR_THREAD=5000 +CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST_FOR_THREAD=5000 +CONFIG_MRP_MAX_RETRANS=3 + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + diff --git a/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c3 b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c3 new file mode 100644 index 0000000..f534f3b --- /dev/null +++ b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c3 @@ -0,0 +1,64 @@ +CONFIG_IDF_TARGET="esp32c3" + +# Arduino Settings +CONFIG_FREERTOS_HZ=1000 +CONFIG_AUTOSTART_ARDUINO=y + +# Log Levels +# Boot Messages - Log level +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y +# Arduino Log Level +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO=y +# IDF Log Level +CONFIG_LOG_DEFAULT_LEVEL_ERROR=y + +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +#disable BT connection reattempt +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +#enable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0xC000 + +# Disable chip shell +CONFIG_ENABLE_CHIP_SHELL=n + +# Enable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=n + +#enable lwIP route hooks +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y + +# disable softap by default +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n +CONFIG_ENABLE_WIFI_STATION=y +CONFIG_ENABLE_WIFI_AP=n + +# Disable DS Peripheral +CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + +# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1) +# unique local addresses for fabrics(MAX_FABRIC), a link local address(1) +CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 diff --git a/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c6 b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c6 new file mode 100644 index 0000000..301ee1a --- /dev/null +++ b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32c6 @@ -0,0 +1,79 @@ +CONFIG_IDF_TARGET="esp32c6" + +# Arduino Settings +CONFIG_FREERTOS_HZ=1000 +CONFIG_AUTOSTART_ARDUINO=y + +# Log Levels +# Boot Messages - Log level +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y +# Arduino Log Level +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO=y +# IDF Log Level +CONFIG_LOG_DEFAULT_LEVEL_ERROR=y + +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +#disable BT connection reattempt +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +#enable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0xC000 + +# Disable chip shell +CONFIG_ENABLE_CHIP_SHELL=n + +# Enable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=n + +#enable lwIP route hooks +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y + +# disable softap by default +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n +CONFIG_ENABLE_WIFI_STATION=y +CONFIG_ENABLE_WIFI_AP=n + +# Disable DS Peripheral +CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + +# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1) +# unique local addresses for fabrics(MAX_FABRIC), a link local address(1) +CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 + +# libsodium +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y + +# NIMBLE +CONFIG_BT_NIMBLE_EXT_ADV=n +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=y + +# FreeRTOS should use legacy API +CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y + +# Use minimal mDNS +CONFIG_USE_MINIMAL_MDNS=y +CONFIG_ENABLE_EXTENDED_DISCOVERY=y diff --git a/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32s3 b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32s3 new file mode 100644 index 0000000..c7ecfa7 --- /dev/null +++ b/examples/espidf-arduino-matter-light/sdkconfig.defaults.esp32s3 @@ -0,0 +1,64 @@ +CONFIG_IDF_TARGET="esp32s3" + +# Arduino Settings +CONFIG_FREERTOS_HZ=1000 +CONFIG_AUTOSTART_ARDUINO=y + +# Log Levels +# Boot Messages - Log level +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y +# Arduino Log Level +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO=y +# IDF Log Level +CONFIG_LOG_DEFAULT_LEVEL_ERROR=y + +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +#enable BT +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y + +#disable BT connection reattempt +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n + +#enable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=y + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0xC000 + +# Disable chip shell +CONFIG_ENABLE_CHIP_SHELL=n + +# Enable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=n + +#enable lwIP route hooks +CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y +CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y + +# disable softap by default +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n +CONFIG_ENABLE_WIFI_STATION=y +CONFIG_ENABLE_WIFI_AP=n + +# Disable DS Peripheral +CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y + +# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1) +# unique local addresses for fabrics(MAX_FABRIC), a link local address(1) +CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 diff --git a/examples/espidf-ulp-lp/CMakeLists.txt b/examples/espidf-ulp-lp/CMakeLists.txt new file mode 100644 index 0000000..3db148b --- /dev/null +++ b/examples/espidf-ulp-lp/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(lp_core_pulse_counter) diff --git a/examples/espidf-ulp-lp/README.md b/examples/espidf-ulp-lp/README.md new file mode 100644 index 0000000..32318f0 --- /dev/null +++ b/examples/espidf-ulp-lp/README.md @@ -0,0 +1,51 @@ +| Supported Targets | ESP32-C6 | +| ----------------- | -------- | + +This example demonstrates how to program the ULP Core coprocessor to count pulses on an IO while the main CPUs are either running some other code or are in deep sleep. See the README.md file in the upper level 'examples' directory for more information about examples. + +At runtime, the main code running on the ESP (found in lp_core_pulse_counter_example_main.c) loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_lp_core_load_binary` function. Main code configures the ULP program by setting up values of some variables and then starts it using `ulp_lp_core_run`. Once the ULP program is started, it monitors the IO pin for pulses. + +When the ULP program finds an edge in the input signal, it performs debouncing and increments the variable maintaining the total edge count. Once the edge count reaches certain value, ULP triggers wake up from deep sleep. Note that the ULP program keeps running and monitoring the input signal even when the SoC is woken up. + +### Hardware Required + +To run this example, you should have a development board based on any of the chips listed in the supported targets table at the top and a host machine with a serial input connection. + +#### Pin Assignment: + +**Note:** The following pin assignments are used by default. + + +| | Uart Tx | Pulse Count Input | +| ----------------------- | ------- | ----------------- | +| ESP32-C6 | GPIO5 | GPIO6 | +| Host machine | Rx | N/A | + + +## Example Output + +The log output from the serial monitor connected to the main core should indicate that the LP core and the LP UART peripheral have been successfully initialized. The main CPU would then enter deep sleep mode. + +```bash +Using pin 6 as pulse counter input +ULP will wake up processor after every 10 pulses +Not a ULP wakeup, initializing it! +Entering in deep sleep +... +rst:0x5 (SLEEP_WAKEUP),boot:0xc (SPI_FAST_FLASH_BOOT) +... +ULP woke up the main CPU! +Pulse count: 11 +Entering in deep sleep +``` + +The log output from the serial monitor connected to the LP core should display output as below - + +```bash +LP Core pulse counter started +Pulse count: 10, wake-up main CPU +``` + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/examples/espidf-ulp-lp/platformio.ini b/examples/espidf-ulp-lp/platformio.ini new file mode 100644 index 0000000..a8e4db6 --- /dev/null +++ b/examples/espidf-ulp-lp/platformio.ini @@ -0,0 +1,13 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[env:esp32-c6] +platform = espressif32 +framework = espidf +board = esp32-c6-devkitc-1 diff --git a/examples/espidf-ulp-lp/pytest_lp_core_pcnt.py b/examples/espidf-ulp-lp/pytest_lp_core_pcnt.py new file mode 100644 index 0000000..a4d8c0c --- /dev/null +++ b/examples/espidf-ulp-lp/pytest_lp_core_pcnt.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import logging + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_pcnt(dut: Dut) -> None: + + res = dut.expect(r'ULP will wake up processor after every (\d+) pulses') + wakeup_limit = res.group(1).decode('utf-8') + assert (int(wakeup_limit) > 0) + logging.info(f'Wake-up limit: {wakeup_limit} pulses') + + dut.expect_exact('Not a ULP wakeup, initializing it!') + dut.expect_exact('Entering in deep sleep') + + dut.expect_exact('ULP woke up the main CPU!') + + res = dut.expect(r'Pulse count: (\d+)') + pulse_count = res.group(1).decode('utf-8') + logging.info(f'Pulse count: {pulse_count}') + + # Check that pulse count is correct, we could have gotten pulses between triggering + # the wakeup signal and printing the count, but it should at be equal to or greater + assert (int(pulse_count) >= int(wakeup_limit)) diff --git a/examples/espidf-ulp-lp/sdkconfig.defaults b/examples/espidf-ulp-lp/sdkconfig.defaults new file mode 100644 index 0000000..cdc2fb8 --- /dev/null +++ b/examples/espidf-ulp-lp/sdkconfig.defaults @@ -0,0 +1,13 @@ +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=8128 +CONFIG_ULP_SHARED_MEM=0x10 + +# Set log level to Warning to produce clean output +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_BOOTLOADER_LOG_LEVEL=2 +CONFIG_LOG_DEFAULT_LEVEL_WARN=y +CONFIG_LOG_DEFAULT_LEVEL=2 diff --git a/examples/espidf-ulp-lp/src/CMakeLists.txt b/examples/espidf-ulp-lp/src/CMakeLists.txt new file mode 100644 index 0000000..b3825ab --- /dev/null +++ b/examples/espidf-ulp-lp/src/CMakeLists.txt @@ -0,0 +1,23 @@ +idf_component_register(SRCS "lp_core_pulse_counter_example_main.c" + INCLUDE_DIRS ".") + +# +# ULP support additions to component CMakeLists.txt. +# +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_main) +# +# 2. Specify all C and Assembly source files. +# Files should be placed into a separate directory (in this case, ulp/), +# which should not be added to COMPONENT_SRCS. +set(ulp_sources "../ulp/main.c") + +# +# 3. List all the component source files which include automatically +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs "lp_core_pulse_counter_example_main.c") + +# +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}") diff --git a/examples/espidf-ulp-lp/src/Kconfig.projbuild b/examples/espidf-ulp-lp/src/Kconfig.projbuild new file mode 100644 index 0000000..88618ce --- /dev/null +++ b/examples/espidf-ulp-lp/src/Kconfig.projbuild @@ -0,0 +1,20 @@ +menu "Example Configuration" + config EXAMPLE_PULSE_COUNT_PIN + int "Input pin for the pulse counter" + default 6 + help + GPIO pin used as the input for the pulse counter + + config EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT + int "Wake-up pulse count limit" + default 10 + help + Number of pulses counted after which the ULP will wake up the main CPU + + config EXAMPLE_PULSE_COUNT_SIMULATE + bool "Simulate pulses on input pin" + default n + help + The ULP will periodically toggle the input pin to simulate pulses + +endmenu diff --git a/examples/espidf-ulp-lp/src/lp_core_pulse_counter_example_main.c b/examples/espidf-ulp-lp/src/lp_core_pulse_counter_example_main.c new file mode 100644 index 0000000..65bef47 --- /dev/null +++ b/examples/espidf-ulp-lp/src/lp_core_pulse_counter_example_main.c @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* LP core gpio example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include +#include "esp_sleep.h" +#include "driver/gpio.h" +#include "driver/rtc_io.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "ulp_lp_core.h" +#include "ulp_main.h" +#include "lp_core_uart.h" + +extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); +extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); + + +static void init_ulp_program(void); + +void app_main(void) +{ + /* If user is using USB-serial-jtag then idf monitor needs some time to + * re-connect to the USB port. We wait 1 sec here to allow for it to make the reconnection + * before we print anything. Otherwise the chip will go back to sleep again before the user + * has time to monitor any output. + */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Initialize selected GPIO as RTC IO, enable input/output, disable pullup and pulldown */ + printf("Using pin %d as pulse counter input\n", CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_init(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_set_direction(CONFIG_EXAMPLE_PULSE_COUNT_PIN, RTC_GPIO_MODE_INPUT_OUTPUT); + rtc_gpio_pulldown_dis(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_pullup_dis(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + + printf("ULP will wake up processor after every %d pulses\n", CONFIG_EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT); + + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + /* not a wakeup from ULP, load the firmware */ + if (cause != ESP_SLEEP_WAKEUP_ULP) { + printf("Not a ULP wakeup, initializing it! \n"); + init_ulp_program(); + } else { + printf("ULP woke up the main CPU!\n"); + printf("Pulse count: %"PRIu32"\n", ulp_pulse_count); + } + + /* Go back to sleep, only the ULP will run */ + printf("Entering in deep sleep\n\n"); + + /* Small delay to ensure the messages are printed */ + ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup()); + + esp_deep_sleep_start(); +} + +static void init_ulp_program(void) +{ + lp_core_uart_cfg_t uart_cfg = LP_CORE_UART_DEFAULT_CONFIG(); + + ESP_ERROR_CHECK(lp_core_uart_init(&uart_cfg)); + + esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)); + ESP_ERROR_CHECK(err); + + /* Start the program */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + err = ulp_lp_core_run(&cfg); + ESP_ERROR_CHECK(err); +} diff --git a/examples/espidf-ulp-lp/ulp/main.c b/examples/espidf-ulp-lp/ulp/main.c new file mode 100644 index 0000000..6a45c04 --- /dev/null +++ b/examples/espidf-ulp-lp/ulp/main.c @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "sdkconfig.h" +#include "ulp_lp_core.h" +#include "ulp_lp_core_utils.h" +#include "ulp_lp_core_gpio.h" +#include "ulp_lp_core_interrupts.h" +#include "ulp_lp_core_print.h" +#include "riscv/csr.h" + +#define DEBOUNCE_INTERVAL_CYCLES 10 // 10 cycles is about 0.625 us at 16 MHz + +#define SIMULATED_PULSE_FREQUENCY_HZ 2 +#define SIMULATED_PULSE_DELAY_US (1000000 / SIMULATED_PULSE_FREQUENCY_HZ) / 2 + +uint32_t pulse_count; +static uint32_t last_trigger_time_cycles; + +void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void) +{ + ulp_lp_core_gpio_clear_intr_status(); + uint32_t trigger_time_cycles = RV_READ_CSR(mcycle); + /* Do some simple debouncing, do not count spurious pulses */ + if (trigger_time_cycles - last_trigger_time_cycles > DEBOUNCE_INTERVAL_CYCLES) { + pulse_count++; + last_trigger_time_cycles = trigger_time_cycles; + } + + if (pulse_count % CONFIG_EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT == 0) { + lp_core_printf("Pulse count: %d, wake-up main CPU\n", pulse_count); + ulp_lp_core_wakeup_main_processor(); + } + +} + + + +int main (void) +{ + lp_core_printf("LP Core pulse counter started\n"); + ulp_lp_core_intr_enable(); + ulp_lp_core_gpio_intr_enable(CONFIG_EXAMPLE_PULSE_COUNT_PIN, LP_IO_INTR_POSEDGE); + + while(1) { + +#if CONFIG_EXAMPLE_PULSE_COUNT_SIMULATE + /* No external device connected to generate pulses, we simulate them ourselves instead */ + ulp_lp_core_delay_us(SIMULATED_PULSE_DELAY_US); + ulp_lp_core_gpio_set_level(CONFIG_EXAMPLE_PULSE_COUNT_PIN, 1); + ulp_lp_core_delay_us(SIMULATED_PULSE_DELAY_US); + ulp_lp_core_gpio_set_level(CONFIG_EXAMPLE_PULSE_COUNT_PIN, 0); +#else + /* Put CPU into a wait state to reduce power consumption while waiting for pulses */ + ulp_lp_core_wait_for_intr(); +#endif //CONFIG_EXAMPLE_PULSE_COUNT_SIMULATE + } + + return 0; +} From e5a15aff41309b508037041798695df92219d792 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:18:56 +0200 Subject: [PATCH 036/175] fix path --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 7336fd3..e74bde0 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -32,7 +32,7 @@ jobs: - "examples/espidf-storage-sdcard" - "examples/espidf-ulp" - "examples/espidf-ulp-riscv" - - "espidf-ulp-lp" + - "examples/espidf-ulp-lp" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From f1be773509081ae0f6aee73b77ff910bb34c1443 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:41:58 +0200 Subject: [PATCH 037/175] add zigbee examples --- .github/workflows/examples.yml | 2 + examples/arduino-zigbee-light/README.md | 65 ++++++ examples/arduino-zigbee-light/include/README | 39 ++++ examples/arduino-zigbee-light/lib/README | 46 ++++ examples/arduino-zigbee-light/platformio.ini | 20 ++ .../src/Zigbee_On_Off_Light.ino | 89 ++++++++ examples/arduino-zigbee-light/test/README | 11 + examples/arduino-zigbee-switch/README.md | 65 ++++++ examples/arduino-zigbee-switch/include/README | 39 ++++ examples/arduino-zigbee-switch/lib/README | 46 ++++ examples/arduino-zigbee-switch/platformio.ini | 20 ++ .../src/Zigbee_On_Off_Switch.ino | 197 ++++++++++++++++++ examples/arduino-zigbee-switch/test/README | 11 + 13 files changed, 650 insertions(+) create mode 100644 examples/arduino-zigbee-light/README.md create mode 100644 examples/arduino-zigbee-light/include/README create mode 100644 examples/arduino-zigbee-light/lib/README create mode 100644 examples/arduino-zigbee-light/platformio.ini create mode 100644 examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino create mode 100644 examples/arduino-zigbee-light/test/README create mode 100644 examples/arduino-zigbee-switch/README.md create mode 100644 examples/arduino-zigbee-switch/include/README create mode 100644 examples/arduino-zigbee-switch/lib/README create mode 100644 examples/arduino-zigbee-switch/platformio.ini create mode 100644 examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino create mode 100644 examples/arduino-zigbee-switch/test/README diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index e74bde0..496fd3f 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -18,6 +18,8 @@ jobs: - "examples/arduino-rmt-blink" - "examples/arduino-usb-keyboard" - "examples/arduino-wifiscan" + - "examples/arduino-zigbee-light" + - "examples/arduino-zigbee-switch" - "examples/espidf-arduino-h2zero-BLE_scan" - "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" diff --git a/examples/arduino-zigbee-light/README.md b/examples/arduino-zigbee-light/README.md new file mode 100644 index 0000000..1b9d972 --- /dev/null +++ b/examples/arduino-zigbee-light/README.md @@ -0,0 +1,65 @@ +# Arduino-ESP32 Zigbee On/Off Light Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) on/off light. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* One development board (ESP32-H2 or ESP32-C6) acting as Zigbee coordinator (loaded with Zigbee_On_Off_switch example) +* A USB cable for power supply and programming +* Choose another board (ESP32-H2 or ESP32-C6) as Zigbee end device and upload the Zigbee_On_Off_Light example + +### Configure the Project + +Set the LED GPIO by changing the `LED_PIN` definition. By default, the LED_PIN is `RGB_BUILTIN`. +By default, the `neoPixelWrite` function is used to control the LED. You can change it to digitalWrite to control a simple LED. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash before flashing it to the board. It is recommended to do this if you did changes to the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled` +* In the sketch uncomment function `esp_zb_nvram_erase_at_start(true);` located in `esp_zb_task` function. + +By default, the coordinator network is open for 180s after rebooting or flashing new firmware. After that, the network is closed for adding new devices. +You can change it by editing `esp_zb_bdb_open_network(180);` in `esp_zb_app_signal_handler` function. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/examples/arduino-zigbee-light/include/README b/examples/arduino-zigbee-light/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/arduino-zigbee-light/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/arduino-zigbee-light/lib/README b/examples/arduino-zigbee-light/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/arduino-zigbee-light/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/arduino-zigbee-light/platformio.ini b/examples/arduino-zigbee-light/platformio.ini new file mode 100644 index 0000000..50c013d --- /dev/null +++ b/examples/arduino-zigbee-light/platformio.ini @@ -0,0 +1,20 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + + +[env:esp32-h2-devkitm-1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-h2-devkitm-1 +monitor_speed = 115200 +board_build.partitions = zigbee.csv +board_build.filesystem = spiffs +build_flags = + -DZIGBEE_MODE_ED + -DCORE_DEBUG_LEVEL=5 diff --git a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino new file mode 100644 index 0000000..db22c3d --- /dev/null +++ b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino @@ -0,0 +1,89 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @brief This example demonstrates simple Zigbee light bulb. + * + * The example demonstrates how to use Zigbee library to create a end device light bulb. + * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "ZigbeeCore.h" +#include "ep/ZigbeeLight.h" + +#define LED_PIN RGB_BUILTIN +#define BUTTON_PIN 9 // C6/H2 Boot button +#define ZIGBEE_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */ + +class MyZigbeeLight : public ZigbeeLight { +public: + // Constructor that passes parameters to the base class constructor + MyZigbeeLight(uint8_t endpoint) : ZigbeeLight(endpoint) {} + + // Override the set_on_off function + void setOnOff(bool value) override { + rgbLedWrite(LED_PIN, 255 * value, 255 * value, 255 * value); // Toggle light + } +}; + +MyZigbeeLight zbLight = MyZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); + +/********************* Arduino functions **************************/ +void setup() { + // Init RMT and leave light OFF + rgbLedWrite(LED_PIN, 0, 0, 0); + + // Init button for factory reset + pinMode(BUTTON_PIN, INPUT); + + //Optional: set Zigbee device name and model + zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); + + //Add endpoint to Zigbee Core + log_d("Adding ZigbeeLight endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbLight); + + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE + log_d("Calling Zigbee.begin()"); + Zigbee.begin(); +} + +void loop() { + // Cheking button for factory reset + if (digitalRead(BUTTON_PIN) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(BUTTON_PIN) == LOW) { + delay(50); + if((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.printf("Reseting Zigbee to factory settings, reboot.\n"); + Zigbee.factoryReset(); + } + } + } + delay(100); +} \ No newline at end of file diff --git a/examples/arduino-zigbee-light/test/README b/examples/arduino-zigbee-light/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/examples/arduino-zigbee-light/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/examples/arduino-zigbee-switch/README.md b/examples/arduino-zigbee-switch/README.md new file mode 100644 index 0000000..90a95c3 --- /dev/null +++ b/examples/arduino-zigbee-switch/README.md @@ -0,0 +1,65 @@ +# Arduino-ESP32 Zigbee On/Off Light Switch Example + +This example shows how to configure Zigbee Coordinator and use it as a Home Automation (HA) on/off light switch. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* One development board (ESP32-H2 or ESP32-C6) acting as Zigbee end device (loaded with Zigbee_On_Off_Light example). +* A USB cable for power supply and programming. +* Choose another board (ESP32-H2 or ESP32-C6) as Zigbee coordinator and upload the Zigbee_On_Off_Switch example. + +### Configure the Project + +Set the Button Switch GPIO by changing the `GPIO_INPUT_IO_TOGGLE_SWITCH` definition. By default, it's the pin `9` (BOOT button on ESP32-C6 and ESP32-H2). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the Coordinator Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)`. +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs`. +* Select the COM port: `Tools -> Port: xxx where the `xxx` is the detected COM port. +* Optional: Set debug level to info to see logs from Zigbee stack: `Tools -> Core Debug Level: Info`. + +## Troubleshooting + +If the End device flashed with the example `Zigbee_Light_Bulb` is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* In the `Zigbee_Light_Bulb` example sketch uncomment function `esp_zb_nvram_erase_at_start(true);` located in `esp_zb_task` function. + +By default, the coordinator network is open for 180s after rebooting or flashing new firmware. After that, the network is closed for adding new devices. +You can change it by editing `esp_zb_bdb_open_network(180);` in `esp_zb_app_signal_handler` function. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/examples/arduino-zigbee-switch/include/README b/examples/arduino-zigbee-switch/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/arduino-zigbee-switch/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/arduino-zigbee-switch/lib/README b/examples/arduino-zigbee-switch/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/arduino-zigbee-switch/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/arduino-zigbee-switch/platformio.ini b/examples/arduino-zigbee-switch/platformio.ini new file mode 100644 index 0000000..1ee3bee --- /dev/null +++ b/examples/arduino-zigbee-switch/platformio.ini @@ -0,0 +1,20 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + + +[env:esp32-c6-devkitc-1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-c6-devkitc-1 +monitor_speed = 115200 +board_build.partitions = zigbee_zczr.csv +board_build.filesystem = spiffs +build_flags = + -DZIGBEE_MODE_ZCZR + -DCORE_DEBUG_LEVEL=5 diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino new file mode 100644 index 0000000..27896f1 --- /dev/null +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -0,0 +1,197 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @brief This example demonstrates simple Zigbee light switch. + * + * The example demonstrates how to use Zigbee library to control a light bulb. + * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator (Switch). + * Button switch and Zigbee runs in separate tasks. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ZCZR +#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" +#endif + +#include "ZigbeeCore.h" +#include "ep/ZigbeeSwitch.h" + +#define SWITCH_ENDPOINT_NUMBER 5 + +/* Switch configuration */ +#define GPIO_INPUT_IO_TOGGLE_SWITCH 9 +#define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0])) + +typedef enum { + SWITCH_ON_CONTROL, + SWITCH_OFF_CONTROL, + SWITCH_ONOFF_TOGGLE_CONTROL, + SWITCH_LEVEL_UP_CONTROL, + SWITCH_LEVEL_DOWN_CONTROL, + SWITCH_LEVEL_CYCLE_CONTROL, + SWITCH_COLOR_CONTROL, +} SwitchFunction; + +typedef struct { + uint8_t pin; + SwitchFunction func; +} SwitchData; + +typedef enum { + SWITCH_IDLE, + SWITCH_PRESS_ARMED, + SWITCH_PRESS_DETECTED, + SWITCH_PRESSED, + SWITCH_RELEASE_DETECTED, +} SwitchState; + +static SwitchData buttonFunctionPair[] = {{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}}; + +/* Zigbee switch */ +class MyZigbeeSwitch : public ZigbeeSwitch { +public: + // Constructor that passes parameters to the base class constructor + MyZigbeeSwitch(uint8_t endpoint) : ZigbeeSwitch(endpoint) {} + + // Override the set_on_off function + void readManufacturer(char* manufacturer) override { + //Do what you want with the manufacturer string + Serial.printf("Manufacturer: %s\n", manufacturer); + } + void readModel(char* model) override { + //Do what you want with the model string + Serial.printf("Model: %s\n", model); + } +}; + +MyZigbeeSwitch zbSwitch = MyZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); + +/********************* Zigbee functions **************************/ +static void onZbButton(SwitchData *button_func_pair) { + if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) { + // Send toggle command to the light + zbSwitch.lightToggle(); + } +} + +/********************* GPIO functions **************************/ +static QueueHandle_t gpio_evt_queue = NULL; + +static void IRAM_ATTR onGpioInterrupt(void *arg) { + xQueueSendFromISR(gpio_evt_queue, (SwitchData *)arg, NULL); +} + +static void enableGpioInterrupt(bool enabled) { + for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); ++i) { + if (enabled) { + enableInterrupt((buttonFunctionPair[i]).pin); + } else { + disableInterrupt((buttonFunctionPair[i]).pin); + } + } +} + +/********************* Arduino functions **************************/ +void setup() { + + Serial.begin(115200); + + //Optional: set Zigbee device name and model + zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch"); + + //Optional to allow multiple light to bind to the switch + zbSwitch.allowMultipleBinding(true); + + //Add endpoint to Zigbee Core + log_d("Adding ZigbeeSwitch endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbSwitch); + + //Open network for 180 seconds after boot + Zigbee.setRebootOpenNetwork(180); + + + // Init button switch + for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); i++) { + pinMode(buttonFunctionPair[i].pin, INPUT_PULLUP); + /* create a queue to handle gpio event from isr */ + gpio_evt_queue = xQueueCreate(10, sizeof(SwitchData)); + if (gpio_evt_queue == 0) { + log_e("Queue was not created and must not be used"); + while (1); + } + attachInterruptArg(buttonFunctionPair[i].pin, onGpioInterrupt, (void *)(buttonFunctionPair + i), FALLING); + } + + // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode + log_d("Calling Zigbee.begin()"); + Zigbee.begin(ZIGBEE_COORDINATOR); + + Serial.println("Waiting for Light to bound to the switch"); + //Wait for switch to bound to a light: + while(!zbSwitch.isBound()) + { + Serial.printf("."); + delay(500); + } + Serial.println(); +} + +void loop() { + // Handle button switch in loop() + uint8_t pin = 0; + SwitchData buttonSwitch; + static SwitchState buttonState = SWITCH_IDLE; + bool eventFlag = false; + + + /* check if there is any queue received, if yes read out the buttonSwitch */ + if (xQueueReceive(gpio_evt_queue, &buttonSwitch, portMAX_DELAY)) { + pin = buttonSwitch.pin; + enableGpioInterrupt(false); + eventFlag = true; + } + while (eventFlag) { + bool value = digitalRead(pin); + switch (buttonState) { + case SWITCH_IDLE: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_IDLE; break; + case SWITCH_PRESS_DETECTED: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_RELEASE_DETECTED; break; + case SWITCH_RELEASE_DETECTED: + buttonState = SWITCH_IDLE; + /* callback to button_handler */ + (*onZbButton)(&buttonSwitch); + break; + default: break; + } + if (buttonState == SWITCH_IDLE) { + enableGpioInterrupt(true); + eventFlag = false; + break; + } + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + // print the bound lights every 10 seconds + static uint32_t lastPrint = 0; + if (millis() - lastPrint > 10000) { + lastPrint = millis(); + zbSwitch.printBoundDevices(); + } +} diff --git a/examples/arduino-zigbee-switch/test/README b/examples/arduino-zigbee-switch/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/examples/arduino-zigbee-switch/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html From 2008d8594a15f41d6b2075c4f39e92859049dceb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:15:17 +0200 Subject: [PATCH 038/175] disable zigbee examples needs merge of the open zigbee Arduino PR --- .github/workflows/examples.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 496fd3f..f290816 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -18,8 +18,8 @@ jobs: - "examples/arduino-rmt-blink" - "examples/arduino-usb-keyboard" - "examples/arduino-wifiscan" - - "examples/arduino-zigbee-light" - - "examples/arduino-zigbee-switch" + #- "examples/arduino-zigbee-light" + #- "examples/arduino-zigbee-switch" - "examples/espidf-arduino-h2zero-BLE_scan" - "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" From c528ba067b2e405d3b15b827236ea5b79a7b6d01 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:31:51 +0200 Subject: [PATCH 039/175] esptool.py v4.8.0 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 59b3e9e..7157ab7 100644 --- a/platform.json +++ b/platform.json @@ -80,7 +80,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.7.5/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.0/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", From dc8b7fa6d148a2ac7e7589b2f96eb02687b56b46 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:59:42 +0200 Subject: [PATCH 040/175] add cmake_utilities for C2 --- examples/espidf-arduino-matter-light/main/idf_component.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/espidf-arduino-matter-light/main/idf_component.yml b/examples/espidf-arduino-matter-light/main/idf_component.yml index 369a76b..0caf8ff 100644 --- a/examples/espidf-arduino-matter-light/main/idf_component.yml +++ b/examples/espidf-arduino-matter-light/main/idf_component.yml @@ -1,3 +1,7 @@ dependencies: espressif/esp_matter: - version: "^1.3.0" \ No newline at end of file + version: "^1.3.0" + espressif/cmake_utilities: + version: "0.*" + rules: + - if: "target in [esp32c2]" From b5d2c18e2c33965934b287e7e5f4fe152c5f15fd Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:03:10 +0200 Subject: [PATCH 041/175] add auto select "espidf" when pio var "custom_sdkconfig" is set --- platform.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform.py b/platform.py index 8c47794..c6162de 100644 --- a/platform.py +++ b/platform.py @@ -39,6 +39,9 @@ class Espressif32Platform(PlatformBase): mcu = variables.get("board_build.mcu", board_config.get("build.mcu", "esp32")) frameworks = variables.get("pioframework", []) + if variables.get("custom_sdkconfig") is not None: + frameworks.append("espidf") + if "arduino" in frameworks: self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False From 723f62046fe95f38ed4d139e987e640b81924476 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:39:39 +0200 Subject: [PATCH 042/175] IDF v5.3.1.240924 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 7157ab7..040c53c 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1/esp-idf-v5.3.1.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.240924/esp-idf-v5.3.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From f8088ef585f5a3aabae0e6266d0df602966a6acb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 17:22:49 +0200 Subject: [PATCH 043/175] Update main.py --- builder/main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builder/main.py b/builder/main.py index bf2f961..32ea2c9 100644 --- a/builder/main.py +++ b/builder/main.py @@ -256,6 +256,9 @@ env.Replace( if mcu in ("esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4") else "tool-xtensa-esp-elf-gdb" ) + or "", + "bin", + "%s-elf-gdb" % toolchain_arch, ), OBJCOPY=join(platform.get_package_dir("tool-esptoolpy") or "", "esptool.py"), RANLIB="%s-elf-gcc-ranlib" % toolchain_arch, From 91db0beaa6ea76866cbe58c2c354ca2adb518cef Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 17:43:36 +0200 Subject: [PATCH 044/175] matter example currently broken --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index f290816..432e359 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -21,7 +21,7 @@ jobs: #- "examples/arduino-zigbee-light" #- "examples/arduino-zigbee-switch" - "examples/espidf-arduino-h2zero-BLE_scan" - - "examples/espidf-arduino-matter-light" + #- "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" - "examples/espidf-blink" From 99a2f8379790a6a27dfd07b8f1ae111f4a8efc95 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 17:49:35 +0200 Subject: [PATCH 045/175] Update platformio.ini --- examples/arduino-blink/platformio.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index 03eaf2c..ced2072 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -7,6 +7,10 @@ ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html +[platformio] +; Workaround for Windows path length limit +core_dir = .platformio + [env:esp-wrover-kit] platform = espressif32 framework = arduino From 9467fb462137bde6eec1abdc78ad66b6b4762855 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 17:49:53 +0200 Subject: [PATCH 046/175] Update platformio.ini --- examples/arduino-rmt-blink/platformio.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/arduino-rmt-blink/platformio.ini b/examples/arduino-rmt-blink/platformio.ini index e3c6bea..4238998 100644 --- a/examples/arduino-rmt-blink/platformio.ini +++ b/examples/arduino-rmt-blink/platformio.ini @@ -1,3 +1,7 @@ +[platformio] +; Workaround for Windows path length limit +core_dir = .platformio + [env:esp32-s2] platform = espressif32 framework = arduino From 6ac746fbd4c06fa2028e6c8db2a788a1e6192da6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 18:00:49 +0200 Subject: [PATCH 047/175] Update platformio.ini --- examples/arduino-blink/platformio.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index ced2072..03eaf2c 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -7,10 +7,6 @@ ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html -[platformio] -; Workaround for Windows path length limit -core_dir = .platformio - [env:esp-wrover-kit] platform = espressif32 framework = arduino From fe906d060af3b9ef6abd9b40c30aed92b66ea211 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 12 Oct 2024 18:01:12 +0200 Subject: [PATCH 048/175] Update platformio.ini --- examples/arduino-rmt-blink/platformio.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/arduino-rmt-blink/platformio.ini b/examples/arduino-rmt-blink/platformio.ini index 4238998..e3c6bea 100644 --- a/examples/arduino-rmt-blink/platformio.ini +++ b/examples/arduino-rmt-blink/platformio.ini @@ -1,7 +1,3 @@ -[platformio] -; Workaround for Windows path length limit -core_dir = .platformio - [env:esp32-s2] platform = espressif32 framework = arduino From 570baf36c4bc6f2b9ef2f33cd3ab6e719260599e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:37:14 +0200 Subject: [PATCH 049/175] Update examples.yml --- .github/workflows/examples.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 432e359..05c3fa5 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -44,12 +44,31 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.11" - - name: Install dependencies + - name: Install Windows dependencies run: | python -m pip install --upgrade pip pip install wheel pip install -U https://github.com/platformio/platformio/archive/develop.zip pio pkg install --global --platform symlink://. - - name: Build examples + if: "matrix.os == 'windows-2022'" + env: + PLATFORMIO_CORE_DIR: C:\plat + PLATFORMIO_PACKAGES_DIR: C:\plat\pack + PLATFORMIO_PLATFORMS_DIR: C:\plat\plat + - name: Build Windows examples + run: pio run -d ${{ matrix.example }} + if: "matrix.os == 'windows-2022'" + env: + PLATFORMIO_CORE_DIR: C:\plat + PLATFORMIO_PACKAGES_DIR: C:\plat\pack + PLATFORMIO_PLATFORMS_DIR: C:\plat\plat + - name: Install Ubuntu Mac dependencies run: | - pio run -d ${{ matrix.example }} + python -m pip install --upgrade pip + pip install wheel + pip install -U https://github.com/platformio/platformio/archive/develop.zip + pio pkg install --global --platform symlink://. + if: "matrix.os != 'windows-2022'" + - name: Build Ubuntu Mac examples + run: pio run -d ${{ matrix.example }} + if: "matrix.os != 'windows-2022'" From c2b9a6f07f1c854e5c246176e38ccaf8d9dc61c0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:37:12 +0200 Subject: [PATCH 050/175] IDF v5.3.1.241016 --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index 040c53c..b519854 100644 --- a/platform.json +++ b/platform.json @@ -12,7 +12,7 @@ "RISC-V" ], "engines": { - "platformio": ">=6.1.15" + "platformio": ">=6.1.16" }, "repository": { "type": "git", @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.240924/esp-idf-v5.3.1.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.241016/esp-idf-v5.3.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 2875e0e6e121c0bc4cd51d197f2260357baec840 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:29:33 +0200 Subject: [PATCH 051/175] Update Zigbee_On_Off_Light.ino --- .../src/Zigbee_On_Off_Light.ino | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino index db22c3d..2f13357 100644 --- a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino +++ b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino @@ -22,7 +22,7 @@ * and also the correct partition scheme must be selected in Tools->Partition Scheme. * * Please check the README.md for instructions and more detailed description. - * + * * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) */ @@ -33,27 +33,22 @@ #include "ZigbeeCore.h" #include "ep/ZigbeeLight.h" -#define LED_PIN RGB_BUILTIN -#define BUTTON_PIN 9 // C6/H2 Boot button -#define ZIGBEE_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */ +#define LED_PIN RGB_BUILTIN +#define BUTTON_PIN 9 // ESP32-C6/H2 Boot button +#define ZIGBEE_LIGHT_ENDPOINT 10 -class MyZigbeeLight : public ZigbeeLight { -public: - // Constructor that passes parameters to the base class constructor - MyZigbeeLight(uint8_t endpoint) : ZigbeeLight(endpoint) {} +ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); - // Override the set_on_off function - void setOnOff(bool value) override { - rgbLedWrite(LED_PIN, 255 * value, 255 * value, 255 * value); // Toggle light - } -}; - -MyZigbeeLight zbLight = MyZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); +/********************* RGB LED functions **************************/ +void setLED(bool value) { + digitalWrite(LED_PIN, value); +} /********************* Arduino functions **************************/ void setup() { - // Init RMT and leave light OFF - rgbLedWrite(LED_PIN, 0, 0, 0); + // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); // Init button for factory reset pinMode(BUTTON_PIN, INPUT); @@ -61,29 +56,32 @@ void setup() { //Optional: set Zigbee device name and model zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); + // Set callback function for light change + zbLight.onLightChange(setLED); + //Add endpoint to Zigbee Core log_d("Adding ZigbeeLight endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbLight); - + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE log_d("Calling Zigbee.begin()"); Zigbee.begin(); } void loop() { - // Cheking button for factory reset + // Checking button for factory reset if (digitalRead(BUTTON_PIN) == LOW) { // Push button pressed // Key debounce handling delay(100); int startTime = millis(); while (digitalRead(BUTTON_PIN) == LOW) { delay(50); - if((millis() - startTime) > 3000) { + if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot - Serial.printf("Reseting Zigbee to factory settings, reboot.\n"); + Serial.printf("Resetting Zigbee to factory settings, reboot.\n"); Zigbee.factoryReset(); } } } delay(100); -} \ No newline at end of file +} From 4e2a1e80429cdd35512c65f3ef0222b940180c6a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:30:25 +0200 Subject: [PATCH 052/175] Update Zigbee_On_Off_Switch.ino --- .../src/Zigbee_On_Off_Switch.ino | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino index 27896f1..09487de 100644 --- a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -23,7 +23,7 @@ * and also the correct partition scheme must be selected in Tools->Partition Scheme. * * Please check the README.md for instructions and more detailed description. - * + * * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) */ @@ -65,24 +65,7 @@ typedef enum { static SwitchData buttonFunctionPair[] = {{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}}; -/* Zigbee switch */ -class MyZigbeeSwitch : public ZigbeeSwitch { -public: - // Constructor that passes parameters to the base class constructor - MyZigbeeSwitch(uint8_t endpoint) : ZigbeeSwitch(endpoint) {} - - // Override the set_on_off function - void readManufacturer(char* manufacturer) override { - //Do what you want with the manufacturer string - Serial.printf("Manufacturer: %s\n", manufacturer); - } - void readModel(char* model) override { - //Do what you want with the model string - Serial.printf("Model: %s\n", model); - } -}; - -MyZigbeeSwitch zbSwitch = MyZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); +ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); /********************* Zigbee functions **************************/ static void onZbButton(SwitchData *button_func_pair) { @@ -111,8 +94,11 @@ static void enableGpioInterrupt(bool enabled) { /********************* Arduino functions **************************/ void setup() { - + Serial.begin(115200); + while (!Serial) { + delay(10); + } //Optional: set Zigbee device name and model zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch"); @@ -126,7 +112,6 @@ void setup() { //Open network for 180 seconds after boot Zigbee.setRebootOpenNetwork(180); - // Init button switch for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); i++) { @@ -143,14 +128,27 @@ void setup() { // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode log_d("Calling Zigbee.begin()"); Zigbee.begin(ZIGBEE_COORDINATOR); - + Serial.println("Waiting for Light to bound to the switch"); //Wait for switch to bound to a light: - while(!zbSwitch.isBound()) - { + while (!zbSwitch.isBound()) { Serial.printf("."); delay(500); } + + // Optional: read manufacturer and model name from the bound light + std::list boundLights = zbSwitch.getBoundDevices(); + //List all bound lights + for (const auto &device : boundLights) { + Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr); + Serial.printf( + "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3], + device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7] + ); + Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr)); + Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr)); + } + Serial.println(); } @@ -160,7 +158,6 @@ void loop() { SwitchData buttonSwitch; static SwitchState buttonState = SWITCH_IDLE; bool eventFlag = false; - /* check if there is any queue received, if yes read out the buttonSwitch */ if (xQueueReceive(gpio_evt_queue, &buttonSwitch, portMAX_DELAY)) { From 5e86bd80092439b7025c44e7924181550547b6b1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:31:42 +0200 Subject: [PATCH 053/175] Update examples.yml --- .github/workflows/examples.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 05c3fa5..b67cfc6 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -18,8 +18,8 @@ jobs: - "examples/arduino-rmt-blink" - "examples/arduino-usb-keyboard" - "examples/arduino-wifiscan" - #- "examples/arduino-zigbee-light" - #- "examples/arduino-zigbee-switch" + - "examples/arduino-zigbee-light" + - "examples/arduino-zigbee-switch" - "examples/espidf-arduino-h2zero-BLE_scan" #- "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" From 1cb879723aa6ae156e1439c7d46366161d9197a9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:34:00 +0200 Subject: [PATCH 054/175] Update platformio.ini --- examples/arduino-zigbee-light/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arduino-zigbee-light/platformio.ini b/examples/arduino-zigbee-light/platformio.ini index 50c013d..2160dc3 100644 --- a/examples/arduino-zigbee-light/platformio.ini +++ b/examples/arduino-zigbee-light/platformio.ini @@ -9,7 +9,7 @@ [env:esp32-h2-devkitm-1] -platform = https://github.com/pioarduino/platform-espressif32.git#develop +platform = espressif32 framework = arduino board = esp32-h2-devkitm-1 monitor_speed = 115200 From 62a6fecf634bfcbc3116d278cab6584941dc9d16 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:34:18 +0200 Subject: [PATCH 055/175] Update platformio.ini --- examples/arduino-zigbee-switch/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arduino-zigbee-switch/platformio.ini b/examples/arduino-zigbee-switch/platformio.ini index 1ee3bee..0c3ce6a 100644 --- a/examples/arduino-zigbee-switch/platformio.ini +++ b/examples/arduino-zigbee-switch/platformio.ini @@ -9,7 +9,7 @@ [env:esp32-c6-devkitc-1] -platform = https://github.com/pioarduino/platform-espressif32.git#develop +platform = espressif32 framework = arduino board = esp32-c6-devkitc-1 monitor_speed = 115200 From e6d98132a40b54607bc16d95c12077b16f293d28 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 19:01:21 +0200 Subject: [PATCH 056/175] Update examples.yml --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index b67cfc6..9b75400 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -21,7 +21,7 @@ jobs: - "examples/arduino-zigbee-light" - "examples/arduino-zigbee-switch" - "examples/espidf-arduino-h2zero-BLE_scan" - #- "examples/espidf-arduino-matter-light" + - "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" - "examples/espidf-blink" From 25b262e01b3527e82a3122b2b84db3f218b1f641 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 22 Oct 2024 18:53:17 +0200 Subject: [PATCH 057/175] esptool.py v4.8.1.1 s2 s3 usb jtag reset fix --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index b519854..54c0a27 100644 --- a/platform.json +++ b/platform.json @@ -80,7 +80,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.0/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.1.1/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", From bc938bb1bcd41525a4d05618336117b728beae24 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:40:06 +0200 Subject: [PATCH 058/175] Update platform.py --- platform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.py b/platform.py index c6162de..11f190b 100644 --- a/platform.py +++ b/platform.py @@ -81,10 +81,10 @@ class Espressif32Platform(PlatformBase): # and RISC-V targets. for gdb_package in ("tool-xtensa-esp-elf-gdb", "tool-riscv32-esp-elf-gdb"): self.packages[gdb_package]["optional"] = False - if IS_WINDOWS: + # if IS_WINDOWS: # Note: On Windows GDB v12 is not able to # launch a GDB server in pipe mode while v11 works fine - self.packages[gdb_package]["version"] = "~11.2.0" + # self.packages[gdb_package]["version"] = "~11.2.0" # Common packages for IDF and mixed Arduino+IDF projects if "espidf" in frameworks: From 1f7857f092e75774d389ea9315fcf3226b03c1db Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:41:31 +0200 Subject: [PATCH 059/175] Update gdb 14.2.0+20240403 --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index 54c0a27..6689ab7 100644 --- a/platform.json +++ b/platform.json @@ -69,13 +69,13 @@ "type": "debugger", "optional": true, "owner": "espressif", - "version": "~12.1.0" + "version": "14.2.0+20240403" }, "tool-riscv32-esp-elf-gdb": { "type": "debugger", "optional": true, "owner": "espressif", - "version": "~12.1.0" + "version": "14.2.0+20240403" }, "tool-esptoolpy": { "type": "uploader", From 4dd00072dd9acf50f055e016095ab3d9702c6983 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:51:30 +0200 Subject: [PATCH 060/175] fix owner for gdb --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index 6689ab7..8211e26 100644 --- a/platform.json +++ b/platform.json @@ -68,13 +68,13 @@ "tool-xtensa-esp-elf-gdb": { "type": "debugger", "optional": true, - "owner": "espressif", + "owner": "platformio", "version": "14.2.0+20240403" }, "tool-riscv32-esp-elf-gdb": { "type": "debugger", "optional": true, - "owner": "espressif", + "owner": "platformio", "version": "14.2.0+20240403" }, "tool-esptoolpy": { From 80b42f4daf6530c867fd31d8c69dde8953647f44 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:11:48 +0200 Subject: [PATCH 061/175] Update IDF v5.3.1.241024 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 8211e26..bf25298 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.241016/esp-idf-v5.3.1.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.241024/esp-idf-v5.3.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 74bcd2a008d80328d4f8391f8011ce24013e1077 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:01:05 +0100 Subject: [PATCH 062/175] Update adafruit_matrixportal_esp32s3.json --- boards/adafruit_matrixportal_esp32s3.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/adafruit_matrixportal_esp32s3.json b/boards/adafruit_matrixportal_esp32s3.json index df10505..12bb6b7 100644 --- a/boards/adafruit_matrixportal_esp32s3.json +++ b/boards/adafruit_matrixportal_esp32s3.json @@ -1,8 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32s3_out.ld", - "partitions": "partitions-8MB-tinyuf2.csv" + "partitions": "tinyuf2-partitions-8MB.csv", + "memory_type": "qio_qspi" }, "core": "esp32", "extra_flags": [ From 418b826c3cae2f08ac40052a698609731d3d36cc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:46:59 +0100 Subject: [PATCH 063/175] Use compatible h2zero NimBLE git commit --- examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml b/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml index 98b4cbf..0d925b9 100644 --- a/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml +++ b/examples/espidf-arduino-h2zero-BLE_scan/src/idf_component.yml @@ -4,6 +4,7 @@ dependencies: esp-nimble-cpp: git: https://github.com/h2zero/esp-nimble-cpp.git + version: 877a29a8b1d0022c5e8f67ba8b879316e67b6c3d # # Defining a dependency from the registry: From f249952209fa22fa8522845fa798f2759de55624 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:00:56 +0100 Subject: [PATCH 064/175] Update Zigbee_On_Off_Light.ino --- examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino index 2f13357..30e3cd2 100644 --- a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino +++ b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino @@ -30,8 +30,7 @@ #error "Zigbee end device mode is not selected in Tools->Zigbee mode" #endif -#include "ZigbeeCore.h" -#include "ep/ZigbeeLight.h" +#include "Zigbee.h" #define LED_PIN RGB_BUILTIN #define BUTTON_PIN 9 // ESP32-C6/H2 Boot button @@ -51,7 +50,7 @@ void setup() { digitalWrite(LED_PIN, LOW); // Init button for factory reset - pinMode(BUTTON_PIN, INPUT); + pinMode(BUTTON_PIN, INPUT_PULLUP); //Optional: set Zigbee device name and model zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); From e69093642b763a38f13937f29e3e3ab3f0f4b200 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:01:52 +0100 Subject: [PATCH 065/175] Update Zigbee_On_Off_Switch.ino --- examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino index 09487de..69cf665 100644 --- a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -31,8 +31,7 @@ #error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" #endif -#include "ZigbeeCore.h" -#include "ep/ZigbeeSwitch.h" +#include "Zigbee.h" #define SWITCH_ENDPOINT_NUMBER 5 From 071d5bd0fe461cef6e199eb0ce7028deb24a2124 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:26:09 +0100 Subject: [PATCH 066/175] fix custom partiton table offset calculation --- builder/main.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/builder/main.py b/builder/main.py index 32ea2c9..d00928b 100644 --- a/builder/main.py +++ b/builder/main.py @@ -131,7 +131,7 @@ def _parse_partitions(env): result = [] next_offset = 0 - bound = int(board.get("upload.offset_address", "0x10000"), 16) # default 0x10000 + app_offset = int(board.get("upload.offset_address", "0x10000"), 16) # default 0x10000 with open(partitions_csv) as fp: for line in fp.readlines(): line = line.strip() @@ -140,23 +140,25 @@ def _parse_partitions(env): tokens = [t.strip() for t in line.split(",")] if len(tokens) < 5: continue + bound = 0x10000 if tokens[1] in ("0", "app") else 4 + calculated_offset = (next_offset + bound - 1) & ~(bound - 1) partition = { "name": tokens[0], "type": tokens[1], "subtype": tokens[2], - "offset": tokens[3] or next_offset, + "offset": tokens[3] or calculated_offset, "size": tokens[4], "flags": tokens[5] if len(tokens) > 5 else None } result.append(partition) next_offset = _parse_size(partition["offset"]) if (partition["subtype"] == "ota_0"): - bound = next_offset - next_offset = (next_offset + bound - 1) & ~(bound - 1) + app_offset = next_offset + next_offset = next_offset + _parse_size(partition["size"]) # Configure application partition offset - env.Replace(ESP32_APP_OFFSET=str(hex(bound))) + env.Replace(ESP32_APP_OFFSET=str(hex(app_offset))) # Propagate application offset to debug configurations - env["INTEGRATION_EXTRA_DATA"].update({"application_offset": str(hex(bound))}) + env["INTEGRATION_EXTRA_DATA"].update({"application_offset": str(hex(app_offset))}) return result From 9618b04d64c1bc8365e22d76ce7449b072065304 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:02:11 +0100 Subject: [PATCH 067/175] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e03df55..cb9cdd7 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,12 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Configure a platform option in [platformio.ini](https://docs.platformio.org/page/projectconf.html) file: ### Stable version -espressif Arduino 3.0.4 and IDF 5.1.4+ See `platform` [documentation](https://docs.platformio.org/en/latest/projectconf/sections/env/options/platform/platform.html#projectconf-env-platform) for details. ```ini [env:stable] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = ... ... ``` From c99f00e466caa92a44e49fa89c5258d51ebd1f4b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:17:43 +0100 Subject: [PATCH 068/175] Create esp32-p4.json --- boards/esp32-p4.json | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 boards/esp32-p4.json diff --git a/boards/esp32-p4.json b/boards/esp32-p4.json new file mode 100644 index 0000000..0a05148 --- /dev/null +++ b/boards/esp32-p4.json @@ -0,0 +1,34 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "360000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32p4", + "variant": "esp32p4" + }, + "connectivity": [ + "bluetooth", + "openthread" + ], + "debug": { + "openocd_target": "esp32p4.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-P4 generic", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com", + "vendor": "Espressif" +} From 7d0916030e7fa4c6b0d1351ae6e13739ee6094bd Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:23:39 +0100 Subject: [PATCH 069/175] add P4 to blink example --- examples/arduino-blink/platformio.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index 03eaf2c..39b7f17 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -26,3 +26,10 @@ platform = espressif32 framework = arduino board = esp32-h2-devkitm-1 monitor_speed = 115200 + +[env:esp32-p4] +platform = espressif32 +framework = arduino +board = esp32-p4 +build_flags = -DLED_BUILTIN=2 +monitor_speed = 115200 From c980602b639a39180ea842895abed4b15f36f20c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:29:14 +0100 Subject: [PATCH 070/175] Update Zigbee_On_Off_Switch.ino --- .../src/Zigbee_On_Off_Switch.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino index 69cf665..e38734a 100644 --- a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -70,6 +70,7 @@ ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); static void onZbButton(SwitchData *button_func_pair) { if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) { // Send toggle command to the light + Serial.println("Toggling light"); zbSwitch.lightToggle(); } } @@ -93,7 +94,6 @@ static void enableGpioInterrupt(bool enabled) { /********************* Arduino functions **************************/ void setup() { - Serial.begin(115200); while (!Serial) { delay(10); @@ -106,7 +106,7 @@ void setup() { zbSwitch.allowMultipleBinding(true); //Add endpoint to Zigbee Core - log_d("Adding ZigbeeSwitch endpoint to Zigbee Core"); + Serial.println("Adding ZigbeeSwitch endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbSwitch); //Open network for 180 seconds after boot @@ -118,19 +118,22 @@ void setup() { /* create a queue to handle gpio event from isr */ gpio_evt_queue = xQueueCreate(10, sizeof(SwitchData)); if (gpio_evt_queue == 0) { - log_e("Queue was not created and must not be used"); - while (1); + Serial.println("Queue creating failed, rebooting..."); + ESP.restart(); } attachInterruptArg(buttonFunctionPair[i].pin, onGpioInterrupt, (void *)(buttonFunctionPair + i), FALLING); } // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode - log_d("Calling Zigbee.begin()"); - Zigbee.begin(ZIGBEE_COORDINATOR); + if (!Zigbee.begin(ZIGBEE_COORDINATOR)) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } Serial.println("Waiting for Light to bound to the switch"); //Wait for switch to bound to a light: - while (!zbSwitch.isBound()) { + while (!zbSwitch.bound()) { Serial.printf("."); delay(500); } From 10c6155a1de95a278e095cdf1848670973f92de6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:30:15 +0100 Subject: [PATCH 071/175] Update Zigbee_On_Off_Light.ino --- .../src/Zigbee_On_Off_Light.ino | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino index 30e3cd2..92c5904 100644 --- a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino +++ b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino @@ -45,6 +45,10 @@ void setLED(bool value) { /********************* Arduino functions **************************/ void setup() { + Serial.begin(115200); + while (!Serial) { + delay(10); + } // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); @@ -59,12 +63,21 @@ void setup() { zbLight.onLightChange(setLED); //Add endpoint to Zigbee Core - log_d("Adding ZigbeeLight endpoint to Zigbee Core"); + Serial.println("Adding ZigbeeLight endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbLight); // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE - log_d("Calling Zigbee.begin()"); - Zigbee.begin(); + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); } void loop() { @@ -77,10 +90,13 @@ void loop() { delay(50); if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot - Serial.printf("Resetting Zigbee to factory settings, reboot.\n"); + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); Zigbee.factoryReset(); } } + // Toggle light by pressing the button + zbLight.setLight(!zbLight.getLightState()); } delay(100); } From e48457be06b2f4902a33233742fa878541f386e4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:43:50 +0100 Subject: [PATCH 072/175] Update sdkconfig.defaults --- examples/espidf-ulp-lp/sdkconfig.defaults | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/espidf-ulp-lp/sdkconfig.defaults b/examples/espidf-ulp-lp/sdkconfig.defaults index cdc2fb8..054ff6c 100644 --- a/examples/espidf-ulp-lp/sdkconfig.defaults +++ b/examples/espidf-ulp-lp/sdkconfig.defaults @@ -4,8 +4,6 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=8128 -CONFIG_ULP_SHARED_MEM=0x10 - # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_BOOTLOADER_LOG_LEVEL=2 From 417c3b6c0f17b731de903b0cacc996fb276a2971 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:45:28 +0100 Subject: [PATCH 073/175] add P4 to LP example --- examples/espidf-ulp-lp/platformio.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/espidf-ulp-lp/platformio.ini b/examples/espidf-ulp-lp/platformio.ini index a8e4db6..2dd34c5 100644 --- a/examples/espidf-ulp-lp/platformio.ini +++ b/examples/espidf-ulp-lp/platformio.ini @@ -11,3 +11,8 @@ platform = espressif32 framework = espidf board = esp32-c6-devkitc-1 + +[env:esp32-p4] +platform = espressif32 +framework = espidf +board = esp32-p4 From 807b40922c3f37674749d6a88753e83d230913a5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:58:32 +0100 Subject: [PATCH 074/175] Create esp32-p4-evboard.json --- boards/esp32-p4-evboard.json | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 boards/esp32-p4-evboard.json diff --git a/boards/esp32-p4-evboard.json b/boards/esp32-p4-evboard.json new file mode 100644 index 0000000..1ea9283 --- /dev/null +++ b/boards/esp32-p4-evboard.json @@ -0,0 +1,37 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "360000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32p4", + "variant": "esp32p4" + }, + "arduino": { + "partitions": "default_16MB.csv" + }, + "connectivity": [ + "bluetooth", + "openthread" + ], + "debug": { + "openocd_target": "esp32p4.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-P4 Function EV Board", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 512000, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 1500000 + }, + "url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html", + "vendor": "Espressif" +} From ba9e2971dab0d72055ec076df8d8f59da524a093 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:46:03 +0100 Subject: [PATCH 075/175] IDF 5.3.2 release --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index bf25298..86f48a1 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.1.241024/esp-idf-v5.3.1.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From c66fe81234edeb05fc7b5a2d02b0c8dd2fd90e0c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:10:00 +0100 Subject: [PATCH 076/175] prep for "pioarduino-build.py" script --- builder/frameworks/arduino.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 4af76df..4a6edd6 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -33,6 +33,10 @@ build_core = board.get("build.core", "").lower() SConscript("_embed_files.py", exports="env") if "espidf" not in env.subst("$PIOFRAMEWORK"): + if os.path.exists(join(FRAMEWORK_DIR, "tools", "platformio-build.py")): + PIO_BUILD = "platformio-build.py" + else: + PIO_BUILD = "pioarduino-build.py" SConscript( join(DefaultEnvironment().PioPlatform().get_package_dir( - "framework-arduinoespressif32"), "tools", "platformio-build.py")) + "framework-arduinoespressif32"), "tools", PIO_BUILD)) From dc971cca34c75c4059717a75a994d873c539f23e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:12:53 +0100 Subject: [PATCH 077/175] add missing import os --- builder/frameworks/arduino.py | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 4a6edd6..4da9fb5 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -22,6 +22,7 @@ kinds of creative coding, interactive objects, spaces or physical experiences. http://arduino.cc/en/Reference/HomePage """ +import os from os.path import join from SCons.Script import DefaultEnvironment, SConscript From a718463dd3c74201d928e495007da591815d49cb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:17:37 +0100 Subject: [PATCH 078/175] fix not defined var --- builder/frameworks/arduino.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 4da9fb5..fc88952 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -34,7 +34,8 @@ build_core = board.get("build.core", "").lower() SConscript("_embed_files.py", exports="env") if "espidf" not in env.subst("$PIOFRAMEWORK"): - if os.path.exists(join(FRAMEWORK_DIR, "tools", "platformio-build.py")): + if os.path.exists(join(DefaultEnvironment().PioPlatform().get_package_dir( + "framework-arduinoespressif32"), "tools", "platformio-build.py")): PIO_BUILD = "platformio-build.py" else: PIO_BUILD = "pioarduino-build.py" From 5c57372b7f9b3adc7de46b3c2b2dac170ac6a47a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:21:51 +0100 Subject: [PATCH 079/175] Update Zigbee_On_Off_Switch.ino --- .../src/Zigbee_On_Off_Switch.ino | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino index e38734a..e12b8aa 100644 --- a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -138,17 +138,16 @@ void setup() { delay(500); } - // Optional: read manufacturer and model name from the bound light + // Optional: List all bound devices and read manufacturer and model name std::list boundLights = zbSwitch.getBoundDevices(); - //List all bound lights for (const auto &device : boundLights) { - Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr); + Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr); Serial.printf( - "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3], - device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7] + "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], + device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0] ); - Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr)); - Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr)); + Serial.printf("Light manufacturer: %s\r\n", zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr)); + Serial.printf("Light model: %s\r\n", zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr)); } Serial.println(); @@ -191,6 +190,6 @@ void loop() { static uint32_t lastPrint = 0; if (millis() - lastPrint > 10000) { lastPrint = millis(); - zbSwitch.printBoundDevices(); + zbSwitch.printBoundDevices(Serial); } } From 893f57f2bab708d995981bf40fdc51a4f157fdb1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:02:28 +0100 Subject: [PATCH 080/175] esptool.py v4.8.5 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 86f48a1..2f9c7ec 100644 --- a/platform.json +++ b/platform.json @@ -80,7 +80,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.1.1/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.5/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", From 5621a0edc89aa065116242c2627a07f9ea27b1cf Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:51:00 +0100 Subject: [PATCH 081/175] Update Zigbee_On_Off_Light.ino --- .../src/Zigbee_On_Off_Light.ino | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino index 92c5904..6db8bd7 100644 --- a/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino +++ b/examples/arduino-zigbee-light/src/Zigbee_On_Off_Light.ino @@ -32,29 +32,28 @@ #include "Zigbee.h" -#define LED_PIN RGB_BUILTIN -#define BUTTON_PIN 9 // ESP32-C6/H2 Boot button +/* Zigbee light bulb configuration */ #define ZIGBEE_LIGHT_ENDPOINT 10 +uint8_t led = RGB_BUILTIN; +uint8_t button = BOOT_PIN; ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); /********************* RGB LED functions **************************/ void setLED(bool value) { - digitalWrite(LED_PIN, value); + digitalWrite(led, value); } /********************* Arduino functions **************************/ void setup() { Serial.begin(115200); - while (!Serial) { - delay(10); - } + // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, LOW); + pinMode(led, OUTPUT); + digitalWrite(led, LOW); // Init button for factory reset - pinMode(BUTTON_PIN, INPUT_PULLUP); + pinMode(button, INPUT_PULLUP); //Optional: set Zigbee device name and model zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); @@ -82,11 +81,11 @@ void setup() { void loop() { // Checking button for factory reset - if (digitalRead(BUTTON_PIN) == LOW) { // Push button pressed + if (digitalRead(button) == LOW) { // Push button pressed // Key debounce handling delay(100); int startTime = millis(); - while (digitalRead(BUTTON_PIN) == LOW) { + while (digitalRead(button) == LOW) { delay(50); if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot From 894cacc06636567c2960455570a9b6f942a99eb6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 14 Dec 2024 12:42:42 +0100 Subject: [PATCH 082/175] add Hybrid Compile (#73) --- .github/workflows/examples.yml | 12 +- README.md | 2 +- boards/esp32-solo1.json | 10 +- boards/esp32s3_120_16_8-qio_opi.json | 50 +++ builder/build_lib/CMakeLists.txt | 1 + builder/build_lib/arduino-lib-builder-as.S | 0 builder/build_lib/arduino-lib-builder-cpp.cpp | 0 builder/build_lib/arduino-lib-builder-gcc.c | 0 builder/build_lib/idf_component.yml | 12 + builder/build_lib/sketch.cpp | 10 + builder/frameworks/arduino.py | 170 +++++++- builder/frameworks/espidf.py | 410 +++++++++++++++++- builder/main.py | 1 + examples/arduino-blink/platformio.ini | 85 +++- .../src/Zigbee_On_Off_Switch.ino | 7 +- examples/tasmota_platformio_override.ini | 37 ++ platform.json | 6 + platform.py | 19 +- 18 files changed, 791 insertions(+), 41 deletions(-) create mode 100644 boards/esp32s3_120_16_8-qio_opi.json create mode 100644 builder/build_lib/CMakeLists.txt create mode 100644 builder/build_lib/arduino-lib-builder-as.S create mode 100644 builder/build_lib/arduino-lib-builder-cpp.cpp create mode 100644 builder/build_lib/arduino-lib-builder-gcc.c create mode 100644 builder/build_lib/idf_component.yml create mode 100644 builder/build_lib/sketch.cpp create mode 100644 examples/tasmota_platformio_override.ini diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 9b75400..901393b 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -20,6 +20,7 @@ jobs: - "examples/arduino-wifiscan" - "examples/arduino-zigbee-light" - "examples/arduino-zigbee-switch" + - "examples/tasmota" - "examples/espidf-arduino-h2zero-BLE_scan" - "examples/espidf-arduino-matter-light" - "examples/espidf-arduino-blink" @@ -49,7 +50,7 @@ jobs: python -m pip install --upgrade pip pip install wheel pip install -U https://github.com/platformio/platformio/archive/develop.zip - pio pkg install --global --platform symlink://. + pio pkg install --global --platform file://. if: "matrix.os == 'windows-2022'" env: PLATFORMIO_CORE_DIR: C:\plat @@ -57,7 +58,7 @@ jobs: PLATFORMIO_PLATFORMS_DIR: C:\plat\plat - name: Build Windows examples run: pio run -d ${{ matrix.example }} - if: "matrix.os == 'windows-2022'" + if: "matrix.example != 'examples/tasmota' && matrix.os == 'windows-2022'" env: PLATFORMIO_CORE_DIR: C:\plat PLATFORMIO_PACKAGES_DIR: C:\plat\pack @@ -67,8 +68,13 @@ jobs: python -m pip install --upgrade pip pip install wheel pip install -U https://github.com/platformio/platformio/archive/develop.zip - pio pkg install --global --platform symlink://. + pio pkg install --global --platform file://. if: "matrix.os != 'windows-2022'" + - name: git clone Tasmota and add to examples + run: | + git clone -b development --depth 1 https://github.com/arendst/Tasmota.git examples/tasmota + cp examples/tasmota_platformio_override.ini examples/tasmota/platformio_override.ini + if: "matrix.example == 'examples/tasmota' && matrix.os != 'windows-2022'" - name: Build Ubuntu Mac examples run: pio run -d ${{ matrix.example }} if: "matrix.os != 'windows-2022'" diff --git a/README.md b/README.md index cb9cdd7..c43ebe1 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ based on devel branch Arduino 3.1.0 and IDF 5.3.1+ ```ini [env:development] -platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53 +platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53_work_hybrid board = ... ... ``` diff --git a/boards/esp32-solo1.json b/boards/esp32-solo1.json index e87b7e1..906772b 100644 --- a/boards/esp32-solo1.json +++ b/boards/esp32-solo1.json @@ -1,11 +1,8 @@ { "build": { - "arduino":{ - "ldscript": "esp32_out.ld" - }, "core": "esp32", "extra_flags": "-DARDUINO_ESP32_DEV -DARDUINO_USB_CDC_ON_BOOT=0 -DCORE32SOLO1", - "f_cpu": "80000000L", + "f_cpu": "160000000L", "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", @@ -32,6 +29,11 @@ "require_upload_port": true, "speed": 460800 }, + "espidf": { + "custom_sdkconfig": [ + "CONFIG_FREERTOS_UNICORE=y" + ] + }, "url": "https://en.wikipedia.org/wiki/ESP32", "vendor": "Espressif" } diff --git a/boards/esp32s3_120_16_8-qio_opi.json b/boards/esp32s3_120_16_8-qio_opi.json new file mode 100644 index 0000000..e4d20f4 --- /dev/null +++ b/boards/esp32s3_120_16_8-qio_opi.json @@ -0,0 +1,50 @@ +{ + "build": { + "arduino": { + "memory_type": "qio_opi", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "f_boot": "120000000L", + "boot": "qio", + "flash_mode": "qio", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "ESP32-S3 16MB QIO, 8MB OPI PSRAM", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf", + "vendor": "espressif" +} diff --git a/builder/build_lib/CMakeLists.txt b/builder/build_lib/CMakeLists.txt new file mode 100644 index 0000000..1ab83d3 --- /dev/null +++ b/builder/build_lib/CMakeLists.txt @@ -0,0 +1 @@ +idf_component_register(SRCS "sketch.cpp" "arduino-lib-builder-gcc.c" "arduino-lib-builder-cpp.cpp" "arduino-lib-builder-as.S" INCLUDE_DIRS ".") diff --git a/builder/build_lib/arduino-lib-builder-as.S b/builder/build_lib/arduino-lib-builder-as.S new file mode 100644 index 0000000..e69de29 diff --git a/builder/build_lib/arduino-lib-builder-cpp.cpp b/builder/build_lib/arduino-lib-builder-cpp.cpp new file mode 100644 index 0000000..e69de29 diff --git a/builder/build_lib/arduino-lib-builder-gcc.c b/builder/build_lib/arduino-lib-builder-gcc.c new file mode 100644 index 0000000..e69de29 diff --git a/builder/build_lib/idf_component.yml b/builder/build_lib/idf_component.yml new file mode 100644 index 0000000..9402459 --- /dev/null +++ b/builder/build_lib/idf_component.yml @@ -0,0 +1,12 @@ +dependencies: + # Required IDF version + idf: ">=5.1" + espressif/cmake_utilities: + version: "0.*" + espressif/fb_gfx: + version: "master" + path: components/fb_gfx + git: https://github.com/espressif/esp32-arduino-lib-builder.git + require: public + rules: + - if: "target in [esp32, esp32s2, esp32s3, esp32p4]" diff --git a/builder/build_lib/sketch.cpp b/builder/build_lib/sketch.cpp new file mode 100644 index 0000000..10a17a8 --- /dev/null +++ b/builder/build_lib/sketch.cpp @@ -0,0 +1,10 @@ +#include "Arduino.h" + +void setup() { + Serial.begin(115200); +} + +void loop() { + Serial.println("Hello World!"); + delay(1000); +} diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index fc88952..b58527f 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -22,23 +22,179 @@ kinds of creative coding, interactive objects, spaces or physical experiences. http://arduino.cc/en/Reference/HomePage """ +import subprocess +import json +import semantic_version import os +import shutil from os.path import join -from SCons.Script import DefaultEnvironment, SConscript +from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, SConscript +from platformio.package.version import pepver_to_semver +from platformio.project.config import ProjectConfig +from platformio.package.manager.tool import ToolPackageManager env = DefaultEnvironment() +pm = ToolPackageManager() +platform = env.PioPlatform() +config = env.GetProjectConfig() board = env.BoardConfig() -build_core = board.get("build.core", "").lower() +mcu = board.get("build.mcu", "esp32") +board_sdkconfig = board.get("espidf.custom_sdkconfig", "") +entry_custom_sdkconfig = "\n" +flag_custom_sdkconfig = False + +if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): + entry_custom_sdkconfig = env.GetProjectOption("custom_sdkconfig") + flag_custom_sdkconfig = True + +if len(str(board_sdkconfig)) > 2: + flag_custom_sdkconfig = True + +extra_flags = (''.join([element for element in board.get("build.extra_flags", "")])).replace("-D", " ") +framework_reinstall = False +flag_any_custom_sdkconfig = False SConscript("_embed_files.py", exports="env") -if "espidf" not in env.subst("$PIOFRAMEWORK"): - if os.path.exists(join(DefaultEnvironment().PioPlatform().get_package_dir( +flag_any_custom_sdkconfig = os.path.exists(join(platform.get_package_dir("framework-arduinoespressif32-libs"),"sdkconfig")) + +# Esp32-solo1 libs needs adopted settings +if flag_custom_sdkconfig == True and ("CORE32SOLO1" in extra_flags or "CONFIG_FREERTOS_UNICORE=y" in entry_custom_sdkconfig or "CONFIG_FREERTOS_UNICORE=y" in board_sdkconfig): + if len(str(env.GetProjectOption("build_unflags"))) == 2: # No valid env, needs init + env['BUILD_UNFLAGS'] = {} + build_unflags = " ".join(env['BUILD_UNFLAGS']) + build_unflags = build_unflags + " -mdisable-hardware-atomics -ustart_app_other_cores" + new_build_unflags = build_unflags.split() + env.Replace( + BUILD_UNFLAGS=new_build_unflags + ) + +def install_python_deps(): + def _get_installed_pip_packages(): + result = {} + packages = {} + pip_output = subprocess.check_output( + [ + env.subst("$PYTHONEXE"), + "-m", + "pip", + "list", + "--format=json", + "--disable-pip-version-check", + ] + ) + try: + packages = json.loads(pip_output) + except: + print("Warning! Couldn't extract the list of installed Python packages.") + return {} + for p in packages: + result[p["name"]] = pepver_to_semver(p["version"]) + + return result + + deps = { + "wheel": ">=0.35.1", + "PyYAML": ">=6.0.2", + "intelhex": ">=2.3.0" + } + + installed_packages = _get_installed_pip_packages() + packages_to_install = [] + for package, spec in deps.items(): + if package not in installed_packages: + packages_to_install.append(package) + else: + version_spec = semantic_version.Spec(spec) + if not version_spec.match(installed_packages[package]): + packages_to_install.append(package) + + if packages_to_install: + env.Execute( + env.VerboseAction( + ( + '"$PYTHONEXE" -m pip install -U ' + + " ".join( + [ + '"%s%s"' % (p, deps[p]) + for p in packages_to_install + ] + ) + ), + "Installing Arduino Python dependencies", + ) + ) + return + +install_python_deps() + +def get_MD5_hash(phrase): + import hashlib + return hashlib.md5((phrase).encode('utf-8')).hexdigest()[:16] + + +def matching_custom_sdkconfig(): + # check if current env is matching to existing sdkconfig + cust_sdk_is_present = False + matching_sdkconfig = False + last_sdkconfig_path = join(env.subst("$PROJECT_DIR"),"sdkconfig.defaults") + if flag_any_custom_sdkconfig == False: + matching_sdkconfig = True + return matching_sdkconfig, cust_sdk_is_present + if os.path.exists(last_sdkconfig_path) == False: + return matching_sdkconfig, cust_sdk_is_present + if flag_custom_sdkconfig == False: + matching_sdkconfig = False + return matching_sdkconfig, cust_sdk_is_present + with open(last_sdkconfig_path) as src: + line = src.readline() + if line.startswith("# TASMOTA__"): + cust_sdk_is_present = True; + costum_options = entry_custom_sdkconfig + if (line.split("__")[1]).strip() == get_MD5_hash((costum_options).strip() + mcu): + matching_sdkconfig = True + + return matching_sdkconfig, cust_sdk_is_present + +def check_reinstall_frwrk(): + framework_reinstall = False + cust_sdk_is_present = False + matching_sdkconfig = False + if flag_custom_sdkconfig == True: + matching_sdkconfig, cust_sdk_is_present = matching_custom_sdkconfig() + if flag_custom_sdkconfig == False and flag_any_custom_sdkconfig == True: + # case custom sdkconfig exists and a env without "custom_sdkconfig" + framework_reinstall = True + if flag_custom_sdkconfig == True and matching_sdkconfig == False: + # check if current custom sdkconfig is different from existing + framework_reinstall = True + return framework_reinstall + +def call_compile_libs(): + if mcu == "esp32c2": + ARDUINO_FRMWRK_C2_LIB_DIR = join(platform.get_package_dir("framework-arduinoespressif32-libs"),mcu) + ARDUINO_C2_DIR = join(platform.get_package_dir("framework-arduino-c2-skeleton-lib"),mcu) + shutil.copytree(ARDUINO_C2_DIR, ARDUINO_FRMWRK_C2_LIB_DIR, dirs_exist_ok=True) + print("*** Compile Arduino IDF libs for %s ***" % env["PIOENV"]) + SConscript("espidf.py") + +if check_reinstall_frwrk() == True: + print("*** Reinstall Arduino framework libs ***") + shutil.rmtree(platform.get_package_dir("framework-arduinoespressif32-libs")) + ARDUINO_FRMWRK_LIB_URL = str(platform.get_package_spec("framework-arduinoespressif32-libs")).split("uri=",1)[1][:-1] + pm.install(ARDUINO_FRMWRK_LIB_URL) + if flag_custom_sdkconfig == True: + call_compile_libs() + flag_custom_sdkconfig = False + +if flag_custom_sdkconfig == True and flag_any_custom_sdkconfig == False: + call_compile_libs() + +if "arduino" in env.subst("$PIOFRAMEWORK") and "espidf" not in env.subst("$PIOFRAMEWORK") and env.subst("$ARDUINO_LIB_COMPILE_FLAG") in ("Inactive", "True"): + if os.path.exists(join(platform.get_package_dir( "framework-arduinoespressif32"), "tools", "platformio-build.py")): PIO_BUILD = "platformio-build.py" else: PIO_BUILD = "pioarduino-build.py" - SConscript( - join(DefaultEnvironment().PioPlatform().get_package_dir( - "framework-arduinoespressif32"), "tools", PIO_BUILD)) + SConscript(join(platform.get_package_dir("framework-arduinoespressif32"), "tools", PIO_BUILD)) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index fe3c0dd..d9b2c33 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -26,7 +26,9 @@ import subprocess import sys import shutil import os +from os.path import join import re +import requests import platform as sys_platform import click @@ -42,6 +44,7 @@ from platformio import fs, __version__ from platformio.compat import IS_WINDOWS from platformio.proc import exec_command from platformio.builder.tools.piolib import ProjectAsLibBuilder +from platformio.project.config import ProjectConfig from platformio.package.version import get_original_version, pepver_to_semver # Added to avoid conflicts between installed Python packages from @@ -53,13 +56,78 @@ if os.environ.get("PYTHONPATH"): env = DefaultEnvironment() env.SConscript("_embed_files.py", exports="env") +def install_standard_python_deps(): + def _get_installed_standard_pip_packages(): + result = {} + packages = {} + pip_output = subprocess.check_output( + [ + env.subst("$PYTHONEXE"), + "-m", + "pip", + "list", + "--format=json", + "--disable-pip-version-check", + ] + ) + try: + packages = json.loads(pip_output) + except: + print("Warning! Couldn't extract the list of installed Python packages.") + return {} + for p in packages: + result[p["name"]] = pepver_to_semver(p["version"]) + + return result + + deps = { + "wheel": ">=0.35.1", + "PyYAML": ">=6.0.2" + } + + installed_packages = _get_installed_standard_pip_packages() + packages_to_install = [] + for package, spec in deps.items(): + if package not in installed_packages: + packages_to_install.append(package) + else: + version_spec = semantic_version.Spec(spec) + if not version_spec.match(installed_packages[package]): + packages_to_install.append(package) + + if packages_to_install: + env.Execute( + env.VerboseAction( + ( + '"$PYTHONEXE" -m pip install -U ' + + " ".join( + [ + '"%s%s"' % (p, deps[p]) + for p in packages_to_install + ] + ) + ), + "Installing standard Python dependencies", + ) + ) + return + +install_standard_python_deps() + # Allow changes in folders of managed components os.environ["IDF_COMPONENT_OVERWRITE_MANAGED_COMPONENTS"] = "1" platform = env.PioPlatform() +config = env.GetProjectConfig() board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") +flash_speed = board.get("build.f_flash", "40000000L") +flash_frequency = str(flash_speed.replace("000000L", "m")) +flash_mode = board.get("build.flash_mode", "dio") idf_variant = mcu.lower() +flag_custom_sdkonfig = False +flag_custom_component_add = False +flag_custom_component_remove = False IDF5 = ( platform.get_package_version("framework-espidf") @@ -78,7 +146,6 @@ TOOLCHAIN_DIR = platform.get_package_dir( assert os.path.isdir(FRAMEWORK_DIR) assert os.path.isdir(TOOLCHAIN_DIR) -# The latest IDF uses a standalone GDB package which requires at least PlatformIO 6.1.11 if ( ["espidf"] == env.get("PIOFRAMEWORK") and semantic_version.Version.coerce(__version__) @@ -87,9 +154,10 @@ if ( ): print("Warning! Debugging an IDF project requires PlatformIO Core >= 6.1.11!") -# Arduino framework as a component is not compatible with ESP-IDF >5.2 +# Arduino framework as a component is not compatible with ESP-IDF >5.3 if "arduino" in env.subst("$PIOFRAMEWORK"): ARDUINO_FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") + ARDUINO_FRMWRK_LIB_DIR = platform.get_package_dir("framework-arduinoespressif32-libs") # Possible package names in 'package@version' format is not compatible with CMake if "@" in os.path.basename(ARDUINO_FRAMEWORK_DIR): new_path = os.path.join( @@ -109,6 +177,208 @@ SDKCONFIG_PATH = os.path.expandvars(board.get( os.path.join(PROJECT_DIR, "sdkconfig.%s" % env.subst("$PIOENV")), )) +# +# generate modified Arduino IDF sdkconfig, applying settings from "custom_sdkconfig" +# +if config.has_option("env:"+env["PIOENV"], "custom_component_add"): + flag_custom_component_add = True +if config.has_option("env:"+env["PIOENV"], "custom_component_remove"): + flag_custom_component_remove = True + +if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): + flag_custom_sdkonfig = True +if "espidf.custom_sdkconfig" in board: + flag_custom_sdkonfig = True + +def HandleArduinoIDFsettings(env): + def get_MD5_hash(phrase): + import hashlib + return hashlib.md5((phrase).encode('utf-8')).hexdigest()[:16] + + def custom_sdkconfig_file(string): + if not config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): + return "" + sdkconfig_entrys = env.GetProjectOption("custom_sdkconfig").splitlines() + for file in sdkconfig_entrys: + if "http" in file and "://" in file: + response = requests.get(file.split(" ")[0]) + if response.ok: + target = str(response.content.decode('utf-8')) + else: + print("Failed to download:", file) + return "" + return target + if "file://" in file: + file_path = join(PROJECT_DIR,file.lstrip("file://").split(os.path.sep)[-1]) + if os.path.exists(file_path): + with open(file_path, 'r') as file: + target = file.read() + else: + print("File not found:", file_path) + return "" + return target + return "" + + + custom_sdk_config_flags = "" + board_idf_config_flags = "" + sdkconfig_file_flags = "" + custom_sdkconfig_file_str = "" + + if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): + flag_custom_sdkonfig = True + custom_sdk_config_flags = (env.GetProjectOption("custom_sdkconfig").rstrip("\n")) + "\n" + custom_sdkconfig_file_str = custom_sdkconfig_file(sdkconfig_file_flags) + + if "espidf.custom_sdkconfig" in board: + board_idf_config_flags = ('\n'.join([element for element in board.get("espidf.custom_sdkconfig", "")])).rstrip("\n") + "\n" + flag_custom_sdkonfig = True + + if flag_custom_sdkonfig == True: # TDOO duplicated + print("*** Add \"custom_sdkconfig\" settings to IDF sdkconfig.defaults ***") + idf_config_flags = custom_sdk_config_flags + if custom_sdkconfig_file_str != "": + sdkconfig_file_flags = custom_sdkconfig_file_str + "\n" + idf_config_flags = sdkconfig_file_flags + idf_config_flags + idf_config_flags = board_idf_config_flags + idf_config_flags + if flash_frequency != "80m": + idf_config_flags = idf_config_flags + "# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set\n" + esptool_flashfreq_y = "CONFIG_ESPTOOLPY_FLASHFREQ_%s=y\n" % flash_frequency.upper() + esptool_flashfreq_M = "CONFIG_ESPTOOLPY_FLASHFREQ=\"%s\"\n" % flash_frequency + idf_config_flags = idf_config_flags + esptool_flashfreq_y + esptool_flashfreq_M + if flash_mode != "qio": + idf_config_flags = idf_config_flags + "# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set\n" + esptool_flashmode = "CONFIG_ESPTOOLPY_FLASHMODE_%s=y\n" % flash_mode.upper() + if esptool_flashmode not in idf_config_flags: + idf_config_flags = idf_config_flags + esptool_flashmode + if mcu in ("esp32") and "CONFIG_FREERTOS_UNICORE=y" in idf_config_flags: + idf_config_flags = idf_config_flags + "# CONFIG_SPIRAM is not set\n" + + idf_config_flags = idf_config_flags.splitlines() + sdkconfig_src = join(ARDUINO_FRMWRK_LIB_DIR,mcu,"sdkconfig") + + def get_flag(line): + if line.startswith("#") and "is not set" in line: + return line.split(" ")[1] + elif not line.startswith("#") and len(line.split("=")) > 1: + return line.split("=")[0] + else: + return None + + with open(sdkconfig_src) as src: + sdkconfig_dst = os.path.join(PROJECT_DIR, "sdkconfig.defaults") + dst = open(sdkconfig_dst,"w") + dst.write("# TASMOTA__"+ get_MD5_hash(''.join(custom_sdk_config_flags).strip() + mcu) +"\n") + while line := src.readline(): + flag = get_flag(line) + if flag is None: + dst.write(line) + else: + no_match = True + for item in idf_config_flags: + if flag == get_flag(item.replace("\'", "")): + dst.write(item.replace("\'", "")+"\n") + no_match = False + print("Replace:",line,"with:",item.replace("\'", "")) + idf_config_flags.remove(item) + if no_match: + dst.write(line) + for item in idf_config_flags: # are there new flags? + print("Add:",item.replace("\'", "")) + dst.write(item.replace("\'", "")+"\n") + dst.close() + return + else: + return + +def HandleCOMPONENTsettings(env): + if flag_custom_component_add == True or flag_custom_component_remove == True: # todo remove duplicated + import yaml + from yaml import SafeLoader + print("*** \"custom_component\" is used to select managed idf components ***") + if flag_custom_component_remove == True: + idf_custom_component_remove = env.GetProjectOption("custom_component_remove").splitlines() + else: + idf_custom_component_remove = "" + if flag_custom_component_add == True: + idf_custom_component_add = env.GetProjectOption("custom_component_add").splitlines() + else: + idf_custom_component_add = "" + + # search "idf_component.yml" file + try: # 1.st in Arduino framework + idf_component_yml_src = os.path.join(ARDUINO_FRAMEWORK_DIR, "idf_component.yml") + shutil.copy(join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml"),join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml.orig")) + yml_file_dir = idf_component_yml_src + except: # 2.nd Project source + try: + idf_component_yml_src = os.path.join(PROJECT_SRC_DIR, "idf_component.yml") + shutil.copy(join(PROJECT_SRC_DIR,"idf_component.yml"),join(PROJECT_SRC_DIR,"idf_component.yml.orig")) + yml_file_dir = idf_component_yml_src + except: # no idf_component.yml in Project source -> create + idf_component_yml_src = os.path.join(PROJECT_SRC_DIR, "idf_component.yml") + yml_file_dir = idf_component_yml_src + idf_component_yml_str = """ + dependencies: + idf: \">=5.1\" + """ + idf_component_yml = yaml.safe_load(idf_component_yml_str) + with open(idf_component_yml_src, 'w',) as f : + yaml.dump(idf_component_yml,f) + + yaml_file=open(idf_component_yml_src,"r") + idf_component=yaml.load(yaml_file, Loader=SafeLoader) + idf_component_str=json.dumps(idf_component) # convert to json string + idf_component_json=json.loads(idf_component_str) # convert string to json dict + + if idf_custom_component_remove != "": + for entry in idf_custom_component_remove: + # checking if the entry exists before removing + if entry in idf_component_json["dependencies"]: + print("*** Removing component:",entry) + del idf_component_json["dependencies"][entry] + + if idf_custom_component_add != "": + for entry in idf_custom_component_add: + if len(str(entry)) > 4: # too short or empty entry + # add new entrys to json + if "@" in entry: + idf_comp_entry = str(entry.split("@")[0]).replace(" ", "") + idf_comp_vers = str(entry.split("@")[1]).replace(" ", "") + else: + idf_comp_entry = str(entry).replace(" ", "") + idf_comp_vers = "*" + if idf_comp_entry not in idf_component_json["dependencies"]: + print("*** Adding component:", idf_comp_entry, idf_comp_vers) + new_entry = {idf_comp_entry: {"version": idf_comp_vers}} + idf_component_json["dependencies"].update(new_entry) + + idf_component_yml_file = open(yml_file_dir,"w") + yaml.dump(idf_component_json, idf_component_yml_file) + idf_component_yml_file.close() + # print("JSON from modified idf_component.yml:") + # print(json.dumps(idf_component_json)) + return + return + +if flag_custom_component_add == True or flag_custom_component_remove == True: + HandleCOMPONENTsettings(env) + +if flag_custom_sdkonfig == True and "arduino" in env.subst("$PIOFRAMEWORK"): + HandleArduinoIDFsettings(env) + LIB_SOURCE = os.path.join(ProjectConfig.get_instance().get("platformio", "platforms_dir"), "espressif32", "builder", "build_lib") + if not bool(os.path.exists(os.path.join(PROJECT_DIR, ".dummy"))): + shutil.copytree(LIB_SOURCE, os.path.join(PROJECT_DIR, ".dummy")) + PROJECT_SRC_DIR = os.path.join(PROJECT_DIR, ".dummy") + env.Replace( + PROJECT_SRC_DIR=PROJECT_SRC_DIR, + BUILD_FLAGS="", + BUILD_UNFLAGS="", + LINKFLAGS="", + PIOFRAMEWORK="arduino", + ARDUINO_LIB_COMPILE_FLAG="Build", + ) + env["INTEGRATION_EXTRA_DATA"].update({"arduino_lib_compile_flag": env.subst("$ARDUINO_LIB_COMPILE_FLAG")}) def get_project_lib_includes(env): project = ProjectAsLibBuilder(env, "$PROJECT_DIR") @@ -1060,7 +1330,8 @@ def generate_empty_partition_image(binary_path, image_size): ), ) - env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", empty_partition) + if flag_custom_sdkonfig == False: + env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", empty_partition) def get_partition_info(pt_path, pt_offset, pt_params): @@ -1557,7 +1828,8 @@ app_includes = get_app_includes(elf_config) # Compile bootloader # -env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", build_bootloader(sdk_config)) +if flag_custom_sdkonfig == False: + env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", build_bootloader(sdk_config)) # # Target: ESP-IDF menuconfig @@ -1773,6 +2045,78 @@ if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "es env.SConscript("ulp.py", exports="env sdk_config project_config app_includes idf_variant") # +# Compile Arduino IDF sources +# + +if "arduino" in env.get("PIOFRAMEWORK") and "espidf" not in env.get("PIOFRAMEWORK"): + def idf_lib_copy(source, target, env): + env_build = join(env["PROJECT_BUILD_DIR"],env["PIOENV"]) + sdkconfig_h_path = join(env_build,"config","sdkconfig.h") + arduino_libs = ARDUINO_FRMWRK_LIB_DIR + lib_src = join(env_build,"esp-idf") + lib_dst = join(arduino_libs,mcu,"lib") + ld_dst = join(arduino_libs,mcu,"ld") + mem_var = join(arduino_libs,mcu,board.get("build.arduino.memory_type", (board.get("build.flash_mode", "dio") + "_qspi"))) + src = [join(lib_src,x) for x in os.listdir(lib_src)] + src = [folder for folder in src if not os.path.isfile(folder)] # folders only + for folder in src: + files = [join(folder,x) for x in os.listdir(folder)] + for file in files: + if file.strip().endswith(".a"): + shutil.copyfile(file,join(lib_dst,file.split(os.path.sep)[-1])) + + shutil.move(join(lib_dst,"libspi_flash.a"),join(mem_var,"libspi_flash.a")) + shutil.move(join(env_build,"memory.ld"),join(ld_dst,"memory.ld")) + if mcu == "esp32s3": + shutil.move(join(lib_dst,"libesp_psram.a"),join(mem_var,"libesp_psram.a")) + shutil.move(join(lib_dst,"libesp_system.a"),join(mem_var,"libesp_system.a")) + shutil.move(join(lib_dst,"libfreertos.a"),join(mem_var,"libfreertos.a")) + shutil.move(join(lib_dst,"libbootloader_support.a"),join(mem_var,"libbootloader_support.a")) + shutil.move(join(lib_dst,"libesp_hw_support.a"),join(mem_var,"libesp_hw_support.a")) + + shutil.copyfile(sdkconfig_h_path,join(mem_var,"include","sdkconfig.h")) + if not bool(os.path.isfile(join(arduino_libs,mcu,"sdkconfig.orig"))): + shutil.move(join(arduino_libs,mcu,"sdkconfig"),join(arduino_libs,mcu,"sdkconfig.orig")) + shutil.copyfile(join(env.subst("$PROJECT_DIR"),"sdkconfig."+env["PIOENV"]),join(arduino_libs,mcu,"sdkconfig")) + shutil.copyfile(join(env.subst("$PROJECT_DIR"),"sdkconfig."+env["PIOENV"]),join(arduino_libs,"sdkconfig")) + print("*** Copied compiled %s IDF libraries to Arduino framework ***" % idf_variant) + + pio_exe_path = shutil.which("platformio"+(".exe" if IS_WINDOWS else "")) + pio_cmd = env["PIOENV"] + env.Execute( + env.VerboseAction( + ( + '"%s" run -e ' % pio_exe_path + + " ".join(['"%s"' % pio_cmd]) + ), + "*** Starting Arduino compile %s with custom libraries ***" % pio_cmd, + ) + ) + if flag_custom_component_add == True or flag_custom_component_remove == True: + try: + shutil.copy(join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml.orig"),join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml")) + print("*** Original Arduino \"idf_component.yml\" restored ***") + except: + print("*** Original Arduino \"idf_component.yml\" couldnt be restored ***") + env.AddPostAction("checkprogsize", idf_lib_copy) + +if "espidf" in env.get("PIOFRAMEWORK") and (flag_custom_component_add == True or flag_custom_component_remove == True): + def idf_custom_component(source, target, env): + try: + shutil.copy(join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml.orig"),join(ARDUINO_FRAMEWORK_DIR,"idf_component.yml")) + print("*** Original Arduino \"idf_component.yml\" restored ***") + except: + try: + shutil.copy(join(PROJECT_SRC_DIR,"idf_component.yml.orig"),join(PROJECT_SRC_DIR,"idf_component.yml")) + print("*** Original \"idf_component.yml\" restored ***") + except: # no "idf_component.yml" in source folder + try: + os.remove(join(PROJECT_SRC_DIR,"idf_component.yml")) + print("*** pioarduino generated \"idf_component.yml\" removed ***") + except: + print("*** \"idf_component.yml\" couldnt be removed ***") + env.AddPostAction("checkprogsize", idf_custom_component) +# # Process OTA partition and image # @@ -1785,7 +2129,10 @@ ota_partition_params = get_partition_info( if ota_partition_params["size"] and ota_partition_params["offset"]: # Generate an empty image if OTA is enabled in partition table ota_partition_image = os.path.join("$BUILD_DIR", "ota_data_initial.bin") - generate_empty_partition_image(ota_partition_image, ota_partition_params["size"]) + if "arduino" in env.subst("$PIOFRAMEWORK"): + ota_partition_image = os.path.join(ARDUINO_FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin") + else: + generate_empty_partition_image(ota_partition_image, ota_partition_params["size"]) env.Append( FLASH_EXTRA_IMAGES=[ @@ -1797,18 +2144,61 @@ if ota_partition_params["size"] and ota_partition_params["offset"]: ) ] ) + EXTRA_IMG_DIR = join(env.subst("$PROJECT_DIR"), "variants", "tasmota") + env.Append( + FLASH_EXTRA_IMAGES=[ + (offset, join(EXTRA_IMG_DIR, img)) for offset, img in board.get("upload.arduino.flash_extra_images", []) + ] + ) + +def _parse_size(value): + if isinstance(value, int): + return value + elif value.isdigit(): + return int(value) + elif value.startswith("0x"): + return int(value, 16) + elif value[-1].upper() in ("K", "M"): + base = 1024 if value[-1].upper() == "K" else 1024 * 1024 + return int(value[:-1]) * base + return value # # Configure application partition offset # -env.Replace( - ESP32_APP_OFFSET=get_app_partition_offset( - env.subst("$PARTITIONS_TABLE_CSV"), partition_table_offset - ) -) +partitions_csv = env.subst("$PARTITIONS_TABLE_CSV") +result = [] +next_offset = 0 +bound = int(board.get("upload.offset_address", "0x10000"), 16) # default 0x10000 +with open(partitions_csv) as fp: + for line in fp.readlines(): + line = line.strip() + if not line or line.startswith("#"): + continue + tokens = [t.strip() for t in line.split(",")] + if len(tokens) < 5: + continue + partition = { + "name": tokens[0], + "type": tokens[1], + "subtype": tokens[2], + "offset": tokens[3] or next_offset, + "size": tokens[4], + "flags": tokens[5] if len(tokens) > 5 else None + } + result.append(partition) + next_offset = _parse_size(partition["offset"]) + if (partition["subtype"] == "ota_0"): + bound = next_offset + next_offset = (next_offset + bound - 1) & ~(bound - 1) +env.Replace(ESP32_APP_OFFSET=str(hex(bound))) + +# # Propagate application offset to debug configurations +# + env["INTEGRATION_EXTRA_DATA"].update( {"application_offset": env.subst("$ESP32_APP_OFFSET")} ) diff --git a/builder/main.py b/builder/main.py index d00928b..4c770f0 100644 --- a/builder/main.py +++ b/builder/main.py @@ -300,6 +300,7 @@ env.Replace( ), ESP32_APP_OFFSET=env.get("INTEGRATION_EXTRA_DATA").get("application_offset"), + ARDUINO_LIB_COMPILE_FLAG="Inactive", PROGSUFFIX=".elf" ) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index 39b7f17..bd12d55 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -7,25 +7,94 @@ ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html -[env:esp-wrover-kit] +[env:esp32solo1] platform = espressif32 framework = arduino -board = esp-wrover-kit +board = esp32-solo1 +build_flags = -DLED_BUILTIN=2 +custom_component_remove = + espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/esp32-camera + espressif/libsodium + espressif/esp-modbus + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/rmaker_common + +[env:esp32-c2-devkitm-1] +platform = espressif32 +framework = arduino +board = esp32-c2-devkitm-1 monitor_speed = 115200 -build_flags = - -DLED_BUILTIN=2 - +custom_sdkconfig = 'CONFIG_IDF_TARGET="esp32c2"' +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/esp32-camera + espressif/libsodium + espressif/esp-modbus + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/rmaker_common + +[env:esp32s3-qio_opi_per] +; OPI Performance settings -> Display use +platform = espressif32 +framework = arduino +board = esp32s3_120_16_8-qio_opi +custom_sdkconfig = CONFIG_SPIRAM_MODE_OCT=y + CONFIG_SPIRAM_SPEED_120M=y + CONFIG_LCD_RGB_ISR_IRAM_SAFE=y + CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y + CONFIG_I2S_ISR_IRAM_SAFE=y + CONFIG_GDMA_ISR_IRAM_SAFE=y + CONFIG_SPIRAM_XIP_FROM_PSRAM=y + CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y + CONFIG_SPIRAM_RODATA=y + CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y + CONFIG_ESP32S3_DATA_CACHE_64KB=y + CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/rmaker_common +custom_component_add = lvgl/lvgl @ ^9.2.2 + [env:esp32-c6-devkitc-1] platform = espressif32 framework = arduino board = esp32-c6-devkitc-1 monitor_speed = 115200 +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/mdns + espressif/esp-dsp + espressif/esp_modem + espressif/esp32-camera [env:esp32-h2-devkitm-1] platform = espressif32 framework = arduino board = esp32-h2-devkitm-1 monitor_speed = 115200 +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/mdns + espressif/esp-dsp + espressif/esp_modem + espressif/esp32-camera [env:esp32-p4] platform = espressif32 @@ -33,3 +102,9 @@ framework = arduino board = esp32-p4 build_flags = -DLED_BUILTIN=2 monitor_speed = 115200 +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/mdns + espressif/esp-dsp + espressif/esp_modem + espressif/esp32-camera diff --git a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino index e12b8aa..56d23cd 100644 --- a/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino +++ b/examples/arduino-zigbee-switch/src/Zigbee_On_Off_Switch.ino @@ -33,10 +33,10 @@ #include "Zigbee.h" +/* Zigbee switch configuration */ #define SWITCH_ENDPOINT_NUMBER 5 -/* Switch configuration */ -#define GPIO_INPUT_IO_TOGGLE_SWITCH 9 +#define GPIO_INPUT_IO_TOGGLE_SWITCH BOOT_PIN #define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0])) typedef enum { @@ -95,9 +95,6 @@ static void enableGpioInterrupt(bool enabled) { /********************* Arduino functions **************************/ void setup() { Serial.begin(115200); - while (!Serial) { - delay(10); - } //Optional: set Zigbee device name and model zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch"); diff --git a/examples/tasmota_platformio_override.ini b/examples/tasmota_platformio_override.ini new file mode 100644 index 0000000..18626bb --- /dev/null +++ b/examples/tasmota_platformio_override.ini @@ -0,0 +1,37 @@ +[platformio] +default_envs = tasmota32-hybrid + +[env:tasmota32_base] +platform = file://. + +[env:tasmota32-hybrid] +extends = env:tasmota32_base +board = esp32 +build_flags = ${env:tasmota32_base.build_flags} + -DHTTPCLIENT_NOSECURE +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + epdiy +custom_sdkconfig = https://raw.githubusercontent.com/pioarduino/sdkconfig/refs/heads/main/sdkconfig_tasmota_esp32 + '# CONFIG_ETH_USE_ESP32_EMAC is not set' + '# CONFIG_ETH_PHY_INTERFACE_RMII is not set' + '# CONFIG_ETH_RMII_CLK_INPUT is not set' + '# CONFIG_ETH_RMII_CLK_IN_GPIO is not set' +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/network_provisioning + espressif/esp-zboss-lib + espressif/esp-zigbee-lib + espressif/esp_rainmaker + espressif/rmaker_common + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/cbor + espressif/qrcode + espressif/esp-sr + espressif/libsodium + espressif/esp-modbus + chmorgan/esp-libhelix-mp3 + espressif/esp32-camera diff --git a/platform.json b/platform.json index 2f9c7ec..74192fe 100644 --- a/platform.json +++ b/platform.json @@ -41,6 +41,12 @@ "owner": "espressif", "version": "" }, + "framework-arduino-c2-skeleton-lib": { + "type": "framework", + "optional": true, + "owner": "espressif", + "version": "https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/c2_arduino_compile_skeleton.zip" + }, "framework-espidf": { "type": "framework", "optional": true, diff --git a/platform.py b/platform.py index 11f190b..b220baa 100644 --- a/platform.py +++ b/platform.py @@ -37,11 +37,12 @@ class Espressif32Platform(PlatformBase): board_config = self.board_config(variables.get("board")) mcu = variables.get("board_build.mcu", board_config.get("build.mcu", "esp32")) + board_sdkconfig = variables.get("board_espidf.custom_sdkconfig", board_config.get("espidf.custom_sdkconfig", "")) + core_variant_board = ''.join(variables.get("board_build.extra_flags", board_config.get("build.extra_flags", ""))) + core_variant_board = core_variant_board.replace("-D", " ") + core_variant_build = (''.join(variables.get("build_flags", []))).replace("-D", " ") frameworks = variables.get("pioframework", []) - if variables.get("custom_sdkconfig") is not None: - frameworks.append("espidf") - if "arduino" in frameworks: self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False @@ -51,6 +52,12 @@ class Espressif32Platform(PlatformBase): dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url + if variables.get("custom_sdkconfig") is not None or len(str(board_sdkconfig)) > 3: + frameworks.append("espidf") + self.packages["framework-espidf"]["optional"] = False + if mcu == "esp32c2": + self.packages["framework-arduino-c2-skeleton-lib"]["optional"] = False + if "buildfs" in targets: filesystem = variables.get("board_build.filesystem", "littlefs") if filesystem == "littlefs": @@ -90,10 +97,10 @@ class Espressif32Platform(PlatformBase): if "espidf" in frameworks: self.packages["toolchain-esp32ulp"]["optional"] = False for p in self.packages: - if p in ("tool-cmake", "tool-ninja"): + if p in ("tool-scons", "tool-cmake", "tool-ninja"): self.packages[p]["optional"] = False -# elif p in ("tool-mconf", "tool-idf") and IS_WINDOWS: -# self.packages[p]["optional"] = False + # elif p in ("tool-mconf", "tool-idf") and IS_WINDOWS: + # self.packages[p]["optional"] = False if mcu in ("esp32", "esp32s2", "esp32s3"): self.packages["toolchain-xtensa-esp-elf"]["optional"] = False From 13763ae99c99f6277d490883b3639a12414c7410 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 14 Dec 2024 12:46:37 +0100 Subject: [PATCH 083/175] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c43ebe1..417f812 100644 --- a/README.md +++ b/README.md @@ -45,12 +45,12 @@ board = ... ... ``` -### Bleeding edged development version -based on devel branch Arduino 3.1.0 and IDF 5.3.1+ +### Development version +based on devel branch Arduino 3.1.0 and IDF 5.3.2 ```ini [env:development] -platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53_work_hybrid +platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53 board = ... ... ``` From 54f1ace1cf40348a7f3f533f29b377609eac072e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:00:54 +0100 Subject: [PATCH 084/175] set Arduino compile option `UPDATE_NOCRYPT` in example Tasmota --- examples/tasmota_platformio_override.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/tasmota_platformio_override.ini b/examples/tasmota_platformio_override.ini index 18626bb..3c13dfc 100644 --- a/examples/tasmota_platformio_override.ini +++ b/examples/tasmota_platformio_override.ini @@ -9,6 +9,7 @@ extends = env:tasmota32_base board = esp32 build_flags = ${env:tasmota32_base.build_flags} -DHTTPCLIENT_NOSECURE + -DUPDATE_NOCRYPT lib_ignore = ${env:tasmota32_base.lib_ignore} Micro-RTSP epdiy From 738e12f1363eae043d9d49b42de9714d68159bde Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:37:24 +0100 Subject: [PATCH 085/175] Update C2 Hybrid compile skeleton --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 74192fe..cbd5b8c 100644 --- a/platform.json +++ b/platform.json @@ -45,7 +45,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/c2_arduino_compile_skeleton.zip" + "version": "https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/c2_arduino_compile_skeleton.zip" }, "framework-espidf": { "type": "framework", From 732cd1c2160418538f255645a05029d1a0839fba Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:47:32 +0100 Subject: [PATCH 086/175] Update IDF v5.3.2.241210 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index cbd5b8c..c6ee03a 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241210/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From b795930c27a4e8bf54ae089fd582e65aeb8e6fca Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:52:42 +0100 Subject: [PATCH 087/175] Revert to IDF 5.3.2 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index c6ee03a..cbd5b8c 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241210/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From f7d2fe0d0e20d518f1627d1b7bf44c8ad9397e67 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:18:52 +0100 Subject: [PATCH 088/175] Update pioarduino IDF 5.2 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index cbd5b8c..7659969 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241012/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From a3d20a74dca85d00b1ba86d764e49e8c2a40befa Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:25:16 +0100 Subject: [PATCH 089/175] Update README.md --- README.md | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 417f812..5b4f5f0 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,26 @@ # pioarduino (p)eople (i)nitiated (o)ptimized (arduino) -# Fork of Platformio Espressif 32: development platform for [PlatformIO](https://platformio.org) [![Build Status](https://github.com/pioarduino/platform-espressif32/workflows/Examples/badge.svg)](https://github.com/pioarduino/platform-espressif32/actions) [![Discord](https://img.shields.io/discord/1263397951829708871.svg?logo=discord&logoColor=white&color=5865F2&label=Discord)](https://discord.gg/Nutz9crnZr) [![GitHub Releases](https://img.shields.io/github/downloads/pioarduino/platform-espressif32/total?label=downloads)](https://github.com/pioarduino/platform-espressif32/releases/latest) -> [!NOTE] -> This fork was created due to the lack of ongoing development for the Espressif 32 Arduino Core for PlatformIO. -> -> For additional information, please refer to these GitHub links: -> -> https://github.com/espressif/arduino-esp32/discussions/10039 -> https://github.com/platformio/platform-espressif32/issues/1225 -> https://github.com/espressif/arduino-esp32/pull/8606 -> -> The discussions are self-explanatory, allowing you to draw your own conclusions. - ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and Bluetooth. ESP32 integrates an antenna switch, RF balun, power amplifier, low-noise receive amplifier, filters, and power management modules. -* [Documentation](https://docs.platformio.org/page/platforms/espressif32.html) (advanced usage, packages, boards, frameworks, etc.) -* Issues with boards (wrong / missing). All issues caused from boards will not be fixed from the maintainer(s). A PR needs to be provided to solve. +* Issues with boards (wrong / missing). All issues caused from boards will **not** be fixed from the maintainer(s). A PR needs to be provided to solve. ## IDE Preparation -- [Download and install official Microsoft Visual Studio Code](https://code.visualstudio.com/). PlatformIO IDE is built on top of it. +- [Download and install official Microsoft Visual Studio Code](https://code.visualstudio.com/). pioarduino IDE is built on top of it. - Open the extension manager. -- Search for the official `platformio ide` extension. -- Install PlatformIO IDE extension. - -![image](idesetup.png) +- Search for the `pioarduino ide` extension. +- Install pioarduino IDE extension. # Usage -1. Setup new VSCode PlatformIO project. -1. Configure a platform option in [platformio.ini](https://docs.platformio.org/page/projectconf.html) file: +1. Setup new VSCode pioarduino project. +1. Configure a platform option in platformio.ini file: ### Stable version - -See `platform` [documentation](https://docs.platformio.org/en/latest/projectconf/sections/env/options/platform/platform.html#projectconf-env-platform) for details. +currently espressif Arduino 3.1.0 and IDF 5.3.2.241210 ```ini [env:stable] @@ -46,15 +30,11 @@ board = ... ``` ### Development version -based on devel branch Arduino 3.1.0 and IDF 5.3.2 +espressif Arduino repo branch master and latest compiled Arduino libs ```ini [env:development] -platform = https://github.com/pioarduino/platform-espressif32.git#Arduino/IDF53 +platform = https://github.com/pioarduino/platform-espressif32.git#develop board = ... ... ``` - -# Configuration - -Please navigate to [documentation](https://docs.platformio.org/page/platforms/espressif32.html). From 75b0f95289ed66c601eb595092d5705164e4346d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:32:07 +0100 Subject: [PATCH 090/175] Update release_zips.yml --- .github/workflows/release_zips.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_zips.yml b/.github/workflows/release_zips.yml index 2c50ca2..5f25ce2 100644 --- a/.github/workflows/release_zips.yml +++ b/.github/workflows/release_zips.yml @@ -3,7 +3,7 @@ name: Create zip file with recursive source clone for release on: push: tags: - - 51* + - 53* jobs: release_zips: From 7f5765b7b8e8c5bffbb240752b0c59a62436a51e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:13:09 +0100 Subject: [PATCH 091/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b4f5f0..52d5308 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ board = ... ``` ### Development version -espressif Arduino repo branch master and latest compiled Arduino libs +espressif Arduino repo branch release/v3.1.x and latest compiled Arduino libs ```ini [env:development] From 36e6f68c529b49eed2d79d19162a25f9641494c0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:01:57 +0100 Subject: [PATCH 092/175] Reconfigure IDF project if dependencies changed --- builder/frameworks/espidf.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index d9b2c33..a1ff9c2 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -405,13 +405,15 @@ def is_cmake_reconfigure_required(cmake_api_reply_dir): ] cmake_preconf_dir = os.path.join(BUILD_DIR, "config") deafult_sdk_config = os.path.join(PROJECT_DIR, "sdkconfig.defaults") + idf_deps_lock = os.path.join(PROJECT_DIR, "dependencies.lock") + ninja_buildfile = os.path.join(BUILD_DIR, "build.ninja") for d in (cmake_api_reply_dir, cmake_preconf_dir): if not os.path.isdir(d) or not os.listdir(d): return True if not os.path.isfile(cmake_cache_file): return True - if not os.path.isfile(os.path.join(BUILD_DIR, "build.ninja")): + if not os.path.isfile(ninja_buildfile): return True if not os.path.isfile(SDKCONFIG_PATH) or os.path.getmtime( SDKCONFIG_PATH @@ -421,6 +423,10 @@ def is_cmake_reconfigure_required(cmake_api_reply_dir): deafult_sdk_config ) > os.path.getmtime(cmake_cache_file): return True + if os.path.isfile(idf_deps_lock) and os.path.getmtime( + idf_deps_lock + ) > os.path.getmtime(ninja_buildfile): + return True if any( os.path.getmtime(f) > os.path.getmtime(cmake_cache_file) for f in cmake_txt_files + [cmake_preconf_dir, FRAMEWORK_DIR] From a4443dd962bb88c9a1ffea9e13749eb44c351bc6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:18:06 +0100 Subject: [PATCH 093/175] use espressif Arduino branch "master" --- platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.py b/platform.py index b220baa..629ff8a 100644 --- a/platform.py +++ b/platform.py @@ -47,7 +47,7 @@ class Espressif32Platform(PlatformBase): self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False # use latest espressif Arduino libs - URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/release/v3.1.x/package/package_esp32_index.template.json" + URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/master/package/package_esp32_index.template.json" packjdata = requests.get(URL).json() dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url From 77f29afae280de1b14d3d18db06839374045d1d2 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:28:51 +0100 Subject: [PATCH 094/175] Branch master --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 7659969..eeee578 100644 --- a/platform.json +++ b/platform.json @@ -33,7 +33,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/release/v3.1.x.zip" + "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/master.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", From 52902cc933322af33229773b63219d62036b8850 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:52:15 +0100 Subject: [PATCH 095/175] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 52d5308..907a445 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ board = ... ... ``` -### Development version -espressif Arduino repo branch release/v3.1.x and latest compiled Arduino libs +### Development version (Arduino core 3.1.0+ and IDF 5.3.2+) +espressif Arduino repo branch master and latest compiled Arduino libs ```ini [env:development] From c147cbf7d4c2b747fbf4ff75ffb7beb7e259cce6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:19:43 +0100 Subject: [PATCH 096/175] Boards update --- boards/adafruit_feather_esp32c6.json | 38 ++++++++++++++++ boards/adafruit_feather_esp32s3_tft.json | 7 +-- boards/adafruit_matrixportal_esp32s3.json | 2 +- boards/dfrobot_romeo_esp32s3.json | 4 +- boards/freenove_esp32_s3_wroom.json | 54 +++++++++++++++++++++++ boards/freenove_esp32_wrover.json | 39 ++++++++++++++++ boards/heltec_wifi_kit_32_V3.json | 3 +- boards/heltec_wireless_stick_lite.json | 5 +-- boards/rymcu-esp32-s3-devkitc-1.json | 51 +++++++++++++++++++++ boards/seeed_xiao_esp32c6.json | 48 ++++++++++++++++++++ boards/sparkfun_esp32c6_thing_plus.json | 38 ++++++++++++++++ boards/sparkfun_qwiic_pocket_esp32c6.json | 38 ++++++++++++++++ boards/weactstudio_esp32c3coreboard.json | 42 ++++++++++++++++++ boards/wt32-sc01-plus.json | 50 +++++++++++++++++++++ 14 files changed, 407 insertions(+), 12 deletions(-) create mode 100644 boards/adafruit_feather_esp32c6.json create mode 100644 boards/freenove_esp32_s3_wroom.json create mode 100644 boards/freenove_esp32_wrover.json create mode 100644 boards/rymcu-esp32-s3-devkitc-1.json create mode 100644 boards/seeed_xiao_esp32c6.json create mode 100644 boards/sparkfun_esp32c6_thing_plus.json create mode 100644 boards/sparkfun_qwiic_pocket_esp32c6.json create mode 100644 boards/weactstudio_esp32c3coreboard.json create mode 100644 boards/wt32-sc01-plus.json diff --git a/boards/adafruit_feather_esp32c6.json b/boards/adafruit_feather_esp32c6.json new file mode 100644 index 0000000..2eaf8f7 --- /dev/null +++ b/boards/adafruit_feather_esp32c6.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ADAFRUIT_FEATHER_ESP32C6", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "adafruit_feather_esp32c6" + }, + "connectivity": [ + "wifi", + "bluetooth", + "zigbee", + "thread" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Adafruit Feather ESP32-C6", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.adafruit.com/product/5933", + "vendor": "Adafruit" +} diff --git a/boards/adafruit_feather_esp32s3_tft.json b/boards/adafruit_feather_esp32s3_tft.json index 0b1d943..a37b7e4 100644 --- a/boards/adafruit_feather_esp32s3_tft.json +++ b/boards/adafruit_feather_esp32s3_tft.json @@ -1,15 +1,16 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", - "partitions": "partitions-4MB-tinyuf2.csv" + "partitions": "partitions-4MB-tinyuf2.csv", + "memory_type": "qio_qspi" }, "core": "esp32", "extra_flags": [ "-DARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT", "-DARDUINO_USB_CDC_ON_BOOT=1", "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1" + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" ], "f_cpu": "240000000L", "f_flash": "80000000L", diff --git a/boards/adafruit_matrixportal_esp32s3.json b/boards/adafruit_matrixportal_esp32s3.json index 12bb6b7..dfdb07c 100644 --- a/boards/adafruit_matrixportal_esp32s3.json +++ b/boards/adafruit_matrixportal_esp32s3.json @@ -1,7 +1,7 @@ { "build": { "arduino":{ - "partitions": "tinyuf2-partitions-8MB.csv", + "partitions": "partitions-8MB-tinyuf2.csv", "memory_type": "qio_qspi" }, "core": "esp32", diff --git a/boards/dfrobot_romeo_esp32s3.json b/boards/dfrobot_romeo_esp32s3.json index 55e69db..f0810d8 100644 --- a/boards/dfrobot_romeo_esp32s3.json +++ b/boards/dfrobot_romeo_esp32s3.json @@ -1,7 +1,6 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "partitions": "app3M_fat9M_16MB.csv", "memory_type": "qio_opi" }, @@ -10,7 +9,8 @@ "-DARDUINO_DFROBOT_ROMEO_ESP32S3", "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1" + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" ], "f_cpu": "240000000L", "f_flash": "80000000L", diff --git a/boards/freenove_esp32_s3_wroom.json b/boards/freenove_esp32_s3_wroom.json new file mode 100644 index 0000000..ea439ab --- /dev/null +++ b/boards/freenove_esp32_s3_wroom.json @@ -0,0 +1,54 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_USB_CDC_ON_BOOT=0" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Freenove ESP32-S3 WROOM N8R8 (8MB Flash / 8MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board", + "vendor": "Freenove" +} diff --git a/boards/freenove_esp32_wrover.json b/boards/freenove_esp32_wrover.json new file mode 100644 index 0000000..7f1aeba --- /dev/null +++ b/boards/freenove_esp32_wrover.json @@ -0,0 +1,39 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32_DEV", + "-DBOARD_HAS_PSRAM", + "-mfix-esp32-psram-cache-issue", + "-mfix-esp32-psram-cache-strategy=memw" + ], + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wrover-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Freenove ESP32-Wrover", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://store.freenove.com/products/fnk0060", + "vendor": "Freenove" +} diff --git a/boards/heltec_wifi_kit_32_V3.json b/boards/heltec_wifi_kit_32_V3.json index d106319..ba83700 100644 --- a/boards/heltec_wifi_kit_32_V3.json +++ b/boards/heltec_wifi_kit_32_V3.json @@ -1,7 +1,6 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "partitions": "default_8MB.csv" }, "core": "esp32", @@ -21,7 +20,7 @@ ] ], "mcu": "esp32s3", - "variant": "heltec_wifi_kit_32_v3" + "variant": "heltec_wifi_kit_32_V3" }, "connectivity": [ "wifi", diff --git a/boards/heltec_wireless_stick_lite.json b/boards/heltec_wireless_stick_lite.json index 6ffac9a..c7ec8bc 100644 --- a/boards/heltec_wireless_stick_lite.json +++ b/boards/heltec_wireless_stick_lite.json @@ -1,12 +1,9 @@ { "build": { - "arduino":{ - "ldscript": "esp32_out.ld" - }, "core": "esp32", "extra_flags": "-DARDUINO_HELTEC_WIRELESS_STICK_LITE", "f_cpu": "240000000L", - "f_flash": "40000000L", + "f_flash": "80000000L", "flash_mode": "dio", "mcu": "esp32", "variant": "heltec_wireless_stick_lite" diff --git a/boards/rymcu-esp32-s3-devkitc-1.json b/boards/rymcu-esp32-s3-devkitc-1.json new file mode 100644 index 0000000..848537a --- /dev/null +++ b/boards/rymcu-esp32-s3-devkitc-1.json @@ -0,0 +1,51 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "RYMCU ESP32-S3-DevKitC-1-N8R2 (8 MB QD, 2 MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://rymcu.com/products", + "vendor": "RYMCU" +} diff --git a/boards/seeed_xiao_esp32c6.json b/boards/seeed_xiao_esp32c6.json new file mode 100644 index 0000000..224f0e2 --- /dev/null +++ b/boards/seeed_xiao_esp32c6.json @@ -0,0 +1,48 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_XIAO_ESP32C6", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x2886", + "0x0046" + ], + [ + "0x303a", + "0x1001" + ] + ], + "mcu": "esp32c6", + "variant": "XIAO_ESP32C6" + }, + "connectivity": [ + "wifi", + "bluetooth", + "zigbee", + "thread" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Seeed Studio XIAO ESP32C6", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://wiki.seeedstudio.com/XIAO_ESP32C6_Getting_Started/", + "vendor": "Seeed Studio" +} diff --git a/boards/sparkfun_esp32c6_thing_plus.json b/boards/sparkfun_esp32c6_thing_plus.json new file mode 100644 index 0000000..f752f66 --- /dev/null +++ b/boards/sparkfun_esp32c6_thing_plus.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "esp32", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "sparkfun_esp32c6_thing_plus", + "extra_flags": [ + "-DARDUINO_ESP32C6_THING_PLUS", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1" + ] + }, + "connectivity": [ + "wifi", + "bluetooth", + "zigbee", + "thread" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Sparkfun ESP32-C6 Thing Plus", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.sparkfun.com/products/22924", + "vendor": "Sparkfun" +} diff --git a/boards/sparkfun_qwiic_pocket_esp32c6.json b/boards/sparkfun_qwiic_pocket_esp32c6.json new file mode 100644 index 0000000..c627d24 --- /dev/null +++ b/boards/sparkfun_qwiic_pocket_esp32c6.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_SFE_QWIIC_POCKET_ESP32C6", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "sparkfun_esp32c6_qwiic_pocket" + }, + "connectivity": [ + "wifi", + "bluetooth", + "zigbee", + "thread" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "SparkFun ESP32-C6 Qwiic Pocket", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.sparkfun.com/products/22925", + "vendor": "SparkFun" +} diff --git a/boards/weactstudio_esp32c3coreboard.json b/boards/weactstudio_esp32c3coreboard.json new file mode 100644 index 0000000..50f9873 --- /dev/null +++ b/boards/weactstudio_esp32c3coreboard.json @@ -0,0 +1,42 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32C3_DEV", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32c3", + "variant": "esp32c3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "WeAct Studio ESP32C3CoreBoard", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 409600, + "maximum_size": 393216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/WeActStudio/WeActStudio.ESP32C3CoreBoard", + "vendor": "WeAct Studio" +} diff --git a/boards/wt32-sc01-plus.json b/boards/wt32-sc01-plus.json new file mode 100644 index 0000000..bc9eb99 --- /dev/null +++ b/boards/wt32-sc01-plus.json @@ -0,0 +1,50 @@ +{ + "build": { + "arduino":{ + "partitions": "tinyuf2-partitions-16MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_WT32_SC01_PLUS", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0X303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "wt32-sc01-plus" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "wt32-sc01-plus", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.wireless-tag.com/portfolio/wt32-eth01", + "vendor": "Wireless-Tag" +} From e3c581ea54daa95bc9f6a838e0395b62c14e74ca Mon Sep 17 00:00:00 2001 From: Xylopyrographer Date: Fri, 20 Dec 2024 01:36:40 -0700 Subject: [PATCH 097/175] Add JCZN ESP32-2432S028R (CYD) board support (#85) --- boards/jczn_2432s028r.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 boards/jczn_2432s028r.json diff --git a/boards/jczn_2432s028r.json b/boards/jczn_2432s028r.json new file mode 100644 index 0000000..b5c10fa --- /dev/null +++ b/boards/jczn_2432s028r.json @@ -0,0 +1,32 @@ +{ + "build": { + "core": "esp32", + "extra_flags": "-DARDUINO_JCZN_2432S028R", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "qio", + "mcu": "esp32", + "variant": "jczn_2432s028r" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "ESP32-2432S028R CYD", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://pan.jczn1688.com/directlink/1/ESP32%20module/2.8inch_ESP32-2432S028R.rar", + "vendor": "JCZN" +} From 0ba3f1948b41a64240d3427f6dd819bd1d9268a0 Mon Sep 17 00:00:00 2001 From: Xylopyrographer Date: Fri, 20 Dec 2024 01:37:03 -0700 Subject: [PATCH 098/175] Add Waveshare ESP32-S3-Matrix board support (#86) --- boards/ws_esp32_s3_matrix.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 boards/ws_esp32_s3_matrix.json diff --git a/boards/ws_esp32_s3_matrix.json b/boards/ws_esp32_s3_matrix.json new file mode 100644 index 0000000..b2f054a --- /dev/null +++ b/boards/ws_esp32_s3_matrix.json @@ -0,0 +1,32 @@ +{ + "build": { + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "memory_type": "qio_qspi" + "mcu": "esp32s3", + "variant": "ws_esp32_s3_matrix" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Waveshare ESP32-S3-Matrix", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.waveshare.com/wiki/ESP32-S3-Matrix", + "vendor": "Waveshare" +} From d6a505ce30a40ca84096e215f87d41b36f73b63e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 22 Dec 2024 13:14:30 +0100 Subject: [PATCH 099/175] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 907a445..1cf8d79 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ board = ... ... ``` -### Development version (Arduino core 3.1.0+ and IDF 5.3.2+) +### Development version espressif Arduino repo branch master and latest compiled Arduino libs ```ini @@ -38,3 +38,5 @@ platform = https://github.com/pioarduino/platform-espressif32.git#develop board = ... ... ``` + +Looking for sponsor button? There is none. If you want to donate, please spend a litte to a charity organization. From e7a1a34be32d4c4805a92e7b23b3ed0fb9c88a94 Mon Sep 17 00:00:00 2001 From: Jeremiah Rose Date: Sun, 22 Dec 2024 23:20:37 +1100 Subject: [PATCH 100/175] Add `sparkfun_esp32s3_thing_plus` board definition (#89) * Add `sparkfun_esp32s3_thing_plus` board definition * remove obsolete or unnecessary entrys --------- Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com> --- boards/sparkfun_esp32s3_thing_plus.json | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 boards/sparkfun_esp32s3_thing_plus.json diff --git a/boards/sparkfun_esp32s3_thing_plus.json b/boards/sparkfun_esp32s3_thing_plus.json new file mode 100644 index 0000000..1120c77 --- /dev/null +++ b/boards/sparkfun_esp32s3_thing_plus.json @@ -0,0 +1,48 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "sparkfun_esp32s3_thing_plus" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "SPARKFUN_ESP32S3_THING_PLUS", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.sparkfun.com/products/24408", + "vendor": "SparkFun" +} From 316e9c6a2dcd8e3fe44c50487b66f3a70a4e5a5c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 22 Dec 2024 13:25:07 +0100 Subject: [PATCH 101/175] sparkfun_esp32s3_thing_plus has QIO PSRAM --- boards/sparkfun_esp32s3_thing_plus.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/sparkfun_esp32s3_thing_plus.json b/boards/sparkfun_esp32s3_thing_plus.json index 1120c77..5dcaefb 100644 --- a/boards/sparkfun_esp32s3_thing_plus.json +++ b/boards/sparkfun_esp32s3_thing_plus.json @@ -1,7 +1,11 @@ { "build": { + "arduino": { + "memory_type": "qio_qspi" + }, "core": "esp32", "extra_flags": [ + "-DBOARD_HAS_PSRAM", "-DARDUINO_ESP32S3_DEV", "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", From 1e67706ddb91bd3245237030ee2b62a1291f08b6 Mon Sep 17 00:00:00 2001 From: KD Puvvadi Date: Mon, 23 Dec 2024 15:10:45 +0530 Subject: [PATCH 102/175] WaveShare ESP32-S3-Zero support (#90) * Add Waveshare ESP32-S3-Zero board support * add build `extra_flags` * Add PSRAM build flag * Update waveshare_esp32_s3_zero.json --------- Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com> --- boards/waveshare_esp32_s3_zero.json | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 boards/waveshare_esp32_s3_zero.json diff --git a/boards/waveshare_esp32_s3_zero.json b/boards/waveshare_esp32_s3_zero.json new file mode 100644 index 0000000..5965e45 --- /dev/null +++ b/boards/waveshare_esp32_s3_zero.json @@ -0,0 +1,41 @@ +{ + "build": { + "arduino":{ + "memory_type": "qio_qspi" + }, + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32s3", + "variant": "waveshare_esp32_s3_zero", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ] + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Waveshare ESP32-S3-Zero", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.waveshare.com/wiki/ESP32-S3-Zero", + "vendor": "Waveshare" +} From c12f1e22205b3ede29ce08cb2001e22b81f9b81b Mon Sep 17 00:00:00 2001 From: vortigont Date: Mon, 23 Dec 2024 20:43:42 +0900 Subject: [PATCH 103/175] add board huidu_hd_wf2 (#91) An ESP32-S3 board with HUB75 connectors to drive RGB pannels https://www.hdwell.com/Product/index46.html --- boards/huidu_hd_wf2.json | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 boards/huidu_hd_wf2.json diff --git a/boards/huidu_hd_wf2.json b/boards/huidu_hd_wf2.json new file mode 100644 index 0000000..56b4ac3 --- /dev/null +++ b/boards/huidu_hd_wf2.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_HUIDU_HD_WF2", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "wifiduino32s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Huidu HD-WF2", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.hdwell.com/Product/index46.html", + "vendor": "Huidu Tech", + "information_urls": [ + "https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/discussions/667", + "https://github.com/vortigont/FireLamp_JeeUI/wiki/Huidu-HD%E2%80%90WF2" + ] +} From fca71a74d6d89c7e799ef1d059171acc0dca0cd3 Mon Sep 17 00:00:00 2001 From: Kyle Mohr <6644803+kylefmohr@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:26:33 -0600 Subject: [PATCH 104/175] Update ws_esp32_s3_matrix.json (#93) Fixes https://github.com/platformio/platformio-core/issues/5055 --- boards/ws_esp32_s3_matrix.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/ws_esp32_s3_matrix.json b/boards/ws_esp32_s3_matrix.json index b2f054a..d116bc5 100644 --- a/boards/ws_esp32_s3_matrix.json +++ b/boards/ws_esp32_s3_matrix.json @@ -3,7 +3,7 @@ "core": "esp32", "f_cpu": "240000000L", "f_flash": "80000000L", - "memory_type": "qio_qspi" + "memory_type": "qio_qspi", "mcu": "esp32s3", "variant": "ws_esp32_s3_matrix" }, From 3678b61568766336e4000673a2ff0c427c6daec7 Mon Sep 17 00:00:00 2001 From: Justin Wiley <7043966+Sector95@users.noreply.github.com> Date: Tue, 31 Dec 2024 01:34:15 -0800 Subject: [PATCH 105/175] adafruit_qualia_s3_rgb666 Partition CSV Name Fix (#96) * adafruit_qualia_s3_rgb666 partition csv name fix * Update adafruit_qualia_s3_rgb666.json --------- Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com> --- boards/adafruit_qualia_s3_rgb666.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boards/adafruit_qualia_s3_rgb666.json b/boards/adafruit_qualia_s3_rgb666.json index e1607a9..c122ae7 100644 --- a/boards/adafruit_qualia_s3_rgb666.json +++ b/boards/adafruit_qualia_s3_rgb666.json @@ -1,9 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32s3_out.ld", "memory_type": "qio_opi", - "partitions": "partitions-16MB-tinyuf2.csv" + "partitions": "tinyuf2-partitions-16MB.csv" }, "core": "esp32", "extra_flags": [ From 9af319e8d3b2629afbdef5851cd2a2e610d84791 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:19:38 +0100 Subject: [PATCH 106/175] Create lilygo-t3-s3.json --- boards/lilygo-t3-s3.json | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 boards/lilygo-t3-s3.json diff --git a/boards/lilygo-t3-s3.json b/boards/lilygo-t3-s3.json new file mode 100644 index 0000000..6a00b6f --- /dev/null +++ b/boards/lilygo-t3-s3.json @@ -0,0 +1,42 @@ +{ + "build": { + "arduino": { + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_LILYGO_T3_S3_V1_X", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_MODE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "LilyGo T3-S3", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://lilygo.cc/products/t3s3-v1-0", + "vendor": "LilyGo" +} From b8a8a8c06e2fafdea69a063e889bb4da97a9a1d5 Mon Sep 17 00:00:00 2001 From: vortigont Date: Wed, 8 Jan 2025 21:25:21 +0900 Subject: [PATCH 107/175] set dio mode for huidu hd-wf boards (#100) - set dio flash mode for hd-wf boards - add hd-fw4 board --- boards/huidu_hd_wf2.json | 4 +-- boards/huidu_hd_wf4.json | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 boards/huidu_hd_wf4.json diff --git a/boards/huidu_hd_wf2.json b/boards/huidu_hd_wf2.json index 56b4ac3..eecb9d6 100644 --- a/boards/huidu_hd_wf2.json +++ b/boards/huidu_hd_wf2.json @@ -13,7 +13,7 @@ ], "f_cpu": "240000000L", "f_flash": "80000000L", - "flash_mode": "qio", + "flash_mode": "dio", "hwids": [ [ "0x303A", @@ -21,7 +21,7 @@ ] ], "mcu": "esp32s3", - "variant": "wifiduino32s3" + "variant": "huidu_hd_wf2" }, "connectivity": [ "bluetooth", diff --git a/boards/huidu_hd_wf4.json b/boards/huidu_hd_wf4.json new file mode 100644 index 0000000..b0acdff --- /dev/null +++ b/boards/huidu_hd_wf4.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_HUIDU_HD_WF4", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "huidu_hd_wf4" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Huidu HD-WF4", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.hdwell.com/Product/index46.html", + "vendor": "Huidu Tech", + "information_urls": [ + "https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/discussions/667", + "https://github.com/vortigont/FireLamp_JeeUI/wiki/Huidu-HD%E2%80%90WF4" + ] +} From 649c08cfa4a5771b06a5c11cb7485914dc0c43e8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:27:35 +0100 Subject: [PATCH 108/175] IDF 5.3.2.241224 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index eeee578..aa11f84 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241012/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241224/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From e0a7d3dc5ae9b887209736055894dd78cbf80f87 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:00:49 +0100 Subject: [PATCH 109/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cf8d79..9a14897 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and Bluetooth. ESP32 integrates an antenna switch, RF balun, power amplifier, low-noise receive amplifier, filters, and power management modules. -* Issues with boards (wrong / missing). All issues caused from boards will **not** be fixed from the maintainer(s). A PR needs to be provided to solve. +* Issues with boards (wrong / missing). All issues caused from boards will not be fixed from the maintainer(s). A PR needs to be provided against branch `develop` to solve. ## IDE Preparation From 75045ed8e89d7e8d876ce6b725b8561075ac85d6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:33:14 +0100 Subject: [PATCH 110/175] Add files via upload --- boards/yb_esp32s3_amp_v2.json | 47 ++++++++++++++++++++++++++++++++ boards/yb_esp32s3_amp_v3.json | 48 +++++++++++++++++++++++++++++++++ boards/yb_esp32s3_eth.json | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 boards/yb_esp32s3_amp_v2.json create mode 100644 boards/yb_esp32s3_amp_v3.json create mode 100644 boards/yb_esp32s3_eth.json diff --git a/boards/yb_esp32s3_amp_v2.json b/boards/yb_esp32s3_amp_v2.json new file mode 100644 index 0000000..645a8d5 --- /dev/null +++ b/boards/yb_esp32s3_amp_v2.json @@ -0,0 +1,47 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_YB_ESP32S3_AMP_V2", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x1A86", + "0x7523" + ] + ], + "mcu": "esp32s3", + "variant": "yb_esp32s3_amp_v2" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YelloByte YB-ESP32-S3-AMP (Rev.2)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/yellobyte/ESP32-DevBoards-Getting-Started/tree/main/boards/YB-ESP32-S3-AMP", + "vendor": "YelloByte" +} diff --git a/boards/yb_esp32s3_amp_v3.json b/boards/yb_esp32s3_amp_v3.json new file mode 100644 index 0000000..8297e8b --- /dev/null +++ b/boards/yb_esp32s3_amp_v3.json @@ -0,0 +1,48 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_YB_ESP32S3_AMP_V3", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "yb_esp32s3_amp_v3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YelloByte YB-ESP32-S3-AMP (Rev.3)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/yellobyte/ESP32-DevBoards-Getting-Started/tree/main/boards/YB-ESP32-S3-AMP", + "vendor": "YelloByte" +} diff --git a/boards/yb_esp32s3_eth.json b/boards/yb_esp32s3_eth.json new file mode 100644 index 0000000..1d99b67 --- /dev/null +++ b/boards/yb_esp32s3_eth.json @@ -0,0 +1,51 @@ +{ + "build": { + "arduino":{ + "partitions": "default.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_YB_ESP32S3_ETH", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "yb_esp32s3_eth" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YelloByte YB-ESP32-S3-ETH", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/yellobyte/ESP32-DevBoards-Getting-Started/tree/main/boards/YB-ESP32-S3-ETH", + "vendor": "YelloByte" +} From 0c69ff9312f955c63a3249b1d85c47c9ad54be61 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:52:45 +0100 Subject: [PATCH 111/175] pioarduino esptool.py v4.8.6 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index aa11f84..8cd85c0 100644 --- a/platform.json +++ b/platform.json @@ -86,7 +86,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.5/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.6/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", From 36f389e0c9524b2af153f44e91b6dcce842f1790 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:54:53 +0100 Subject: [PATCH 112/175] Delete idesetup.png --- idesetup.png | Bin 71133 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 idesetup.png diff --git a/idesetup.png b/idesetup.png deleted file mode 100644 index faff8fe4f1f4401249a0b47873324858df2dec18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71133 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 i;!H=7?La$$_E*%=UcPsnS2d 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∨` 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%0AfDIr^S zq8fP1H;fhQ~ z`=-3wy}E$!a(FO%2U@m5-j6ZX?$vbHlomIhr*qN{_FbgcTtq>+fQSv}-uXq4eq>?Q z(UDH%UbS_Q9`DEAj2xv!%KMJhqC0iFX^7n1wLR*Qcw*Uh!8TCea@lhW6-wv zY$w_41Ni$8NbwPV?|ZpT=vi`fjALa$hWtXNcftP&nFMD0M^0ZwE$7CAX~Sa$HjkY? zRDJV+cdG5Sgas^@nrD=bF z@fqTq>Nc5I4PUVzVj8E(@$eBF%V$@&55&HBZKz*3uA2*%`*abt-=oI1>!T=m<^6^0 z{n-bts~*;KNA@)tJr}sJTfDD`Q&2kRxxSz_@B2gRVx5XU_Rqya zcw-sBkH=R9MqeBc(?Hw;BcnR#xX4lBCy_`DBvKJ1k!S%Zf~@Rt{pw&_C{TK}NU+&* z?Y!=;<3_2IKfb=Y?n`T`2TmKRW}P=gExvTHT6(!&zLfeto`ea;_b)#N=Le8c*SCbUl)_VwZVZj<$pEH^G5%}1J3Ozy_UW*ZXULgh86=`WE;1d)m$ zi9`!TsRNf~Nzd7RTh0CWeUO+wtU=w4P zNF;hqDuN^uEx;8ORyMl*iJj1!wsZM2GNNM^O5z0*Mf;O1z9l*=NMD*`P@h8c!Q{4C z9PFo#PZykDXbXww%QM7R47T`^xS={t`2;}E=-O;t?VQY}PjTr{nK}0P207M|+Vz5% znDuPzciYtIzsoi>o-_|%Oikn0!CbfSi*0TDO=A3p`seh0zFao>K0ChD4jof{&K|e1 z{taAyraeaH!q~ZNjSO#zzOz3DSByj=(JN9BB#~$VuBfoGQJ&1{q}{_wT(pRgz~xvs zZ0Q_NFE`&E~p=z4{k?om4!A1^sqhW%LcV&VB;H`kXQ)Yg4GJugX759 zEH;0*Ehb)bIpX)3?LEi0$Kdf3dQN)v4buE2dKMjVEka~Bme*a07*qoM6N<$f^`hfZ2$lO From f45bd3f9217a50e6545fa403acd5ddc3e2dc1c09 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 15:45:52 +0100 Subject: [PATCH 113/175] Create waveshare_esp32s3_touch_lcd_128.json --- boards/waveshare_esp32s3_touch_lcd_128.json | 52 +++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 boards/waveshare_esp32s3_touch_lcd_128.json diff --git a/boards/waveshare_esp32s3_touch_lcd_128.json b/boards/waveshare_esp32s3_touch_lcd_128.json new file mode 100644 index 0000000..d619940 --- /dev/null +++ b/boards/waveshare_esp32s3_touch_lcd_128.json @@ -0,0 +1,52 @@ +{ + "build": { + "arduino":{ + "memory_type": "qio_qspi", + "partitions": "default.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_WAVESHARE_ESP32S3_TOUCH_LCD_128", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x1a86", + "0x55d3" + ] + ], + "mcu": "esp32s3", + "variant": "waveshare_esp32s3_touch_lcd_128" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Waveshare ESP32-S3-Touch-LCD-1.28 (16 MB QD, 2MB PSRAM)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.28", + "vendor": "Waveshare" + } From ae4e16842924aa3ff305a8bc0d258cd63f7e02ca Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:01:20 +0100 Subject: [PATCH 114/175] Better handling of IDF virtual environment --- builder/frameworks/espidf.py | 47 ++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index a1ff9c2..d77438e 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1585,11 +1585,37 @@ def get_idf_venv_dir(): def ensure_python_venv_available(): + def _get_idf_venv_python_version(): + try: + version = subprocess.check_output( + [ + get_python_exe(), + "-c", + "import sys;print('{0}.{1}.{2}-{3}.{4}'.format(*list(sys.version_info)))" + ], text=True + ) + return version.strip() + except subprocess.CalledProcessError as e: + print("Failed to extract Python version from IDF virtual env!") + return None + def _is_venv_outdated(venv_data_file): try: with open(venv_data_file, "r", encoding="utf8") as fp: venv_data = json.load(fp) if venv_data.get("version", "") != IDF_ENV_VERSION: + print( + "Warning! IDF virtual environment version changed!" + ) + return True + if ( + venv_data.get("python_version", "") + != _get_idf_venv_python_version() + ): + print( + "Warning! Python version in the IDF virtual environment" + " differs from the current Python!" + ) return True return False except: @@ -1604,7 +1630,7 @@ def ensure_python_venv_available(): if os.path.isdir(venv_dir): try: - print("Removing an oudated IDF virtual environment") + print("Removing an outdated IDF virtual environment") shutil.rmtree(venv_dir) except OSError: print( @@ -1629,8 +1655,12 @@ def ensure_python_venv_available(): venv_data_file = os.path.join(venv_dir, "pio-idf-venv.json") if not os.path.isfile(venv_data_file) or _is_venv_outdated(venv_data_file): _create_venv(venv_dir) + install_python_deps() with open(venv_data_file, "w", encoding="utf8") as fp: - venv_info = {"version": IDF_ENV_VERSION} + venv_info = { + "version": IDF_ENV_VERSION, + "python_version": _get_idf_venv_python_version() + } json.dump(venv_info, fp, indent=2) @@ -1649,11 +1679,10 @@ def get_python_exe(): # -# ESP-IDF requires Python packages with specific versions in a virtual environment +# Ensure Python environment contains everything required for IDF # ensure_python_venv_available() -install_python_deps() # ESP-IDF package doesn't contain .git folder, instead package version is specified # in a special file "version.h" in the root folder of the package @@ -1859,7 +1888,15 @@ libs = find_lib_deps( # Extra flags which need to be explicitly specified in LINKFLAGS section because SCons # cannot merge them correctly extra_flags = filter_args( - link_args["LINKFLAGS"], ["-T", "-u", "-Wl,--start-group", "-Wl,--end-group"] + link_args["LINKFLAGS"], + [ + "-T", + "-u", + "-Wl,--start-group", + "-Wl,--end-group", + "-Wl,--whole-archive", + "-Wl,--no-whole-archive", + ], ) link_args["LINKFLAGS"] = sorted(list(set(link_args["LINKFLAGS"]) - set(extra_flags))) From cd0c9c2e413497cee0a35c671e055eacd001fc6e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:40:39 +0100 Subject: [PATCH 115/175] Add files via upload --- examples/arduino-matter/include/README | 39 ++++ examples/arduino-matter/lib/README | 46 +++++ examples/arduino-matter/platformio.ini | 17 ++ .../arduino-matter/src/MatterColorLight.ino | 180 ++++++++++++++++++ examples/arduino-matter/test/README | 11 ++ 5 files changed, 293 insertions(+) create mode 100644 examples/arduino-matter/include/README create mode 100644 examples/arduino-matter/lib/README create mode 100644 examples/arduino-matter/platformio.ini create mode 100644 examples/arduino-matter/src/MatterColorLight.ino create mode 100644 examples/arduino-matter/test/README diff --git a/examples/arduino-matter/include/README b/examples/arduino-matter/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/arduino-matter/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/arduino-matter/lib/README b/examples/arduino-matter/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/arduino-matter/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/arduino-matter/platformio.ini b/examples/arduino-matter/platformio.ini new file mode 100644 index 0000000..0259643 --- /dev/null +++ b/examples/arduino-matter/platformio.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + + +[env:esp32-c6-devkitc-1] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip +framework = arduino +board_build.partitions = huge_app.csv +build_flags = -DCHIP_HAVE_CONFIG_H +board = esp32-c6-devkitc-1 +monitor_speed = 115200 diff --git a/examples/arduino-matter/src/MatterColorLight.ino b/examples/arduino-matter/src/MatterColorLight.ino new file mode 100644 index 0000000..dd1724f --- /dev/null +++ b/examples/arduino-matter/src/MatterColorLight.ino @@ -0,0 +1,180 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Matter Manager +#include +#include +#include + +// List of Matter Endpoints for this Node +// Color Light Endpoint +MatterColorLight ColorLight; + +// WiFi is manually set and started +const char *ssid = "your-ssid"; // Change this to your WiFi SSID +const char *password = "your-password"; // Change this to your WiFi password + +// it will keep last OnOff & HSV Color state stored, using Preferences +Preferences matterPref; +const char *onOffPrefKey = "OnOff"; +const char *hsvColorPrefKey = "HSV"; + +// set your board RGB LED pin here +#ifdef RGB_BUILTIN +const uint8_t ledPin = RGB_BUILTIN; +#else +const uint8_t ledPin = 2; // Set your pin here if your board has not defined LED_BUILTIN +#warning "Do not forget to set the RGB LED pin" +#endif + +// set your board USER BUTTON pin here +const uint8_t buttonPin = BOOT_PIN; // Set your pin here. Using BOOT Button. + +// Button control +uint32_t button_time_stamp = 0; // debouncing control +bool button_state = false; // false = released | true = pressed +const uint32_t debouceTime = 250; // button debouncing time (ms) +const uint32_t decommissioningTimeout = 5000; // keep the button pressed for 5s, or longer, to decommission + +// Set the RGB LED Light based on the current state of the Color Light +bool setLightState(bool state, espHsvColor_t colorHSV) { + + if (state) { +#ifdef RGB_BUILTIN + espRgbColor_t rgbColor = espHsvColorToRgbColor(colorHSV); + // set the RGB LED + rgbLedWrite(ledPin, rgbColor.r, rgbColor.g, rgbColor.b); +#else + // No Color RGB LED, just use the HSV value (brightness) to control the LED + analogWrite(ledPin, colorHSV.v); +#endif + } else { + digitalWrite(ledPin, LOW); + } + // store last HSV Color and OnOff state for when the Light is restarted / power goes off + matterPref.putBool(onOffPrefKey, state); + matterPref.putUInt(hsvColorPrefKey, colorHSV.h << 16 | colorHSV.s << 8 | colorHSV.v); + // This callback must return the success state to Matter core + return true; +} + +void setup() { + // Initialize the USER BUTTON (Boot button) GPIO that will act as a toggle switch + pinMode(buttonPin, INPUT_PULLUP); + // Initialize the LED (light) GPIO and Matter End Point + pinMode(ledPin, OUTPUT); + + Serial.begin(115200); + + // We start by connecting to a WiFi network + Serial.print("Connecting to "); + Serial.println(ssid); + // Manually connect to WiFi + WiFi.begin(ssid, password); + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\r\nWiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + delay(500); + + // Initialize Matter EndPoint + matterPref.begin("MatterPrefs", false); + // default OnOff state is ON if not stored before + bool lastOnOffState = matterPref.getBool(onOffPrefKey, true); + // default HSV color is blue HSV(169, 254, 254) + uint32_t prefHsvColor = matterPref.getUInt(hsvColorPrefKey, 169 << 16 | 254 << 8 | 254); + espHsvColor_t lastHsvColor = {uint8_t(prefHsvColor >> 16), uint8_t(prefHsvColor >> 8), uint8_t(prefHsvColor)}; + ColorLight.begin(lastOnOffState, lastHsvColor); + // set the callback function to handle the Light state change + ColorLight.onChange(setLightState); + + // lambda functions are used to set the attribute change callbacks + ColorLight.onChangeOnOff([](bool state) { + Serial.printf("Light OnOff changed to %s\r\n", state ? "ON" : "OFF"); + return true; + }); + ColorLight.onChangeColorHSV([](HsvColor_t hsvColor) { + Serial.printf("Light HSV Color changed to (%d,%d,%d)\r\n", hsvColor.h, hsvColor.s, hsvColor.v); + return true; + }); + + // Matter beginning - Last step, after all EndPoints are initialized + Matter.begin(); + // This may be a restart of a already commissioned Matter accessory + if (Matter.isDeviceCommissioned()) { + Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use."); + Serial.printf( + "Initial state: %s | RGB Color: (%d,%d,%d) \r\n", ColorLight ? "ON" : "OFF", ColorLight.getColorRGB().r, ColorLight.getColorRGB().g, + ColorLight.getColorRGB().b + ); + // configure the Light based on initial on-off state and its color + ColorLight.updateAccessory(); + } +} + +void loop() { + // Check Matter Light Commissioning state, which may change during execution of loop() + if (!Matter.isDeviceCommissioned()) { + Serial.println(""); + Serial.println("Matter Node is not commissioned yet."); + Serial.println("Initiate the device discovery in your Matter environment."); + Serial.println("Commission it to your Matter hub with the manual pairing code or QR code"); + Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str()); + Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str()); + // waits for Matter Light Commissioning. + uint32_t timeCount = 0; + while (!Matter.isDeviceCommissioned()) { + delay(100); + if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec + Serial.println("Matter Node not commissioned yet. Waiting for commissioning."); + } + } + Serial.printf( + "Initial state: %s | RGB Color: (%d,%d,%d) \r\n", ColorLight ? "ON" : "OFF", ColorLight.getColorRGB().r, ColorLight.getColorRGB().g, + ColorLight.getColorRGB().b + ); + // configure the Light based on initial on-off state and its color + ColorLight.updateAccessory(); + Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use."); + } + + // A button is also used to control the light + // Check if the button has been pressed + if (digitalRead(buttonPin) == LOW && !button_state) { + // deals with button debouncing + button_time_stamp = millis(); // record the time while the button is pressed. + button_state = true; // pressed. + } + + // Onboard User Button is used as a Light toggle switch or to decommission it + uint32_t time_diff = millis() - button_time_stamp; + if (digitalRead(buttonPin) == HIGH && button_state && time_diff > debouceTime) { + // Toggle button is released - toggle the light + Serial.println("User button released. Toggling Light!"); + ColorLight.toggle(); // Matter Controller also can see the change + button_state = false; // released + } + + // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node + if (button_state && time_diff > decommissioningTimeout) { + Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + ColorLight = false; // turn the light off + Matter.decommission(); + button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so + } +} diff --git a/examples/arduino-matter/test/README b/examples/arduino-matter/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/examples/arduino-matter/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html From f4f8186e38cf71b9b034786a657cd8dcd6917df4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:42:16 +0100 Subject: [PATCH 116/175] Update examples.yml --- .github/workflows/examples.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 901393b..3889dd3 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -22,7 +22,8 @@ jobs: - "examples/arduino-zigbee-switch" - "examples/tasmota" - "examples/espidf-arduino-h2zero-BLE_scan" - - "examples/espidf-arduino-matter-light" + #- "examples/espidf-arduino-matter-light" + - "examples/arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" - "examples/espidf-blink" From c2c6c994cbf1d0df257882bd6826f99458f00fff Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:44:34 +0100 Subject: [PATCH 117/175] rename to matter-light --- .../{arduino-matter => arduino-matter-light}/include/README | 0 examples/{arduino-matter => arduino-matter-light}/lib/README | 0 .../{arduino-matter => arduino-matter-light}/platformio.ini | 0 examples/arduino-matter-light/src/.gitignore | 5 +++++ .../src/MatterColorLight.ino | 0 .../{arduino-matter => arduino-matter-light}/test/README | 0 6 files changed, 5 insertions(+) rename examples/{arduino-matter => arduino-matter-light}/include/README (100%) rename examples/{arduino-matter => arduino-matter-light}/lib/README (100%) rename examples/{arduino-matter => arduino-matter-light}/platformio.ini (100%) create mode 100644 examples/arduino-matter-light/src/.gitignore rename examples/{arduino-matter => arduino-matter-light}/src/MatterColorLight.ino (100%) rename examples/{arduino-matter => arduino-matter-light}/test/README (100%) diff --git a/examples/arduino-matter/include/README b/examples/arduino-matter-light/include/README similarity index 100% rename from examples/arduino-matter/include/README rename to examples/arduino-matter-light/include/README diff --git a/examples/arduino-matter/lib/README b/examples/arduino-matter-light/lib/README similarity index 100% rename from examples/arduino-matter/lib/README rename to examples/arduino-matter-light/lib/README diff --git a/examples/arduino-matter/platformio.ini b/examples/arduino-matter-light/platformio.ini similarity index 100% rename from examples/arduino-matter/platformio.ini rename to examples/arduino-matter-light/platformio.ini diff --git a/examples/arduino-matter-light/src/.gitignore b/examples/arduino-matter-light/src/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/examples/arduino-matter-light/src/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/examples/arduino-matter/src/MatterColorLight.ino b/examples/arduino-matter-light/src/MatterColorLight.ino similarity index 100% rename from examples/arduino-matter/src/MatterColorLight.ino rename to examples/arduino-matter-light/src/MatterColorLight.ino diff --git a/examples/arduino-matter/test/README b/examples/arduino-matter-light/test/README similarity index 100% rename from examples/arduino-matter/test/README rename to examples/arduino-matter-light/test/README From 0cb7a0c50295de77940ee6b137a0a22aca9f9516 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:46:42 +0100 Subject: [PATCH 118/175] Update platformio.ini --- examples/arduino-matter-light/platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arduino-matter-light/platformio.ini b/examples/arduino-matter-light/platformio.ini index 0259643..9c624da 100644 --- a/examples/arduino-matter-light/platformio.ini +++ b/examples/arduino-matter-light/platformio.ini @@ -9,7 +9,7 @@ [env:esp32-c6-devkitc-1] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip +platform = espressif32 framework = arduino board_build.partitions = huge_app.csv build_flags = -DCHIP_HAVE_CONFIG_H From 699d93f88e41df71afd14376ba5353bfece8be74 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:34:32 +0100 Subject: [PATCH 119/175] add check tools --- platform.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platform.json b/platform.json index 8cd85c0..ff77290 100644 --- a/platform.json +++ b/platform.json @@ -117,6 +117,21 @@ "owner": "platformio", "version": "~2.230.0" }, + "tool-cppcheck": { + "optional": true, + "owner": "platformio", + "version": "^1.21100.241030" + }, + "tool-clangtidy": { + "optional": true, + "owner": "platformio", + "version": "^1.190100.0" + }, + "tool-pvs-studio": { + "optional": true, + "owner": "platformio", + "version": "^7.18.59866" + }, "tool-cmake": { "optional": true, "owner": "platformio", From 4649062680c8d31da364dc5bc7604cfb3e8fd3ec Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:37:33 +0100 Subject: [PATCH 120/175] install check tools --- platform.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform.py b/platform.py index 629ff8a..58e1b53 100644 --- a/platform.py +++ b/platform.py @@ -58,6 +58,11 @@ class Espressif32Platform(PlatformBase): if mcu == "esp32c2": self.packages["framework-arduino-c2-skeleton-lib"]["optional"] = False + # Enable check tools only when "check_tool" is active + for p in self.packages: + if p in ("tool-cppcheck", "tool-clangtidy", "tool-pvs-studio"): + self.packages[p]["optional"] = False if str(variables.get("check_tool")).strip("['']") in p else True + if "buildfs" in targets: filesystem = variables.get("board_build.filesystem", "littlefs") if filesystem == "littlefs": From 4c3656cb9fb87953cde012b4d7f0b211ffa1cf67 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:30:30 +0100 Subject: [PATCH 121/175] Update examples.yml --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 3889dd3..cf43a39 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -22,7 +22,7 @@ jobs: - "examples/arduino-zigbee-switch" - "examples/tasmota" - "examples/espidf-arduino-h2zero-BLE_scan" - #- "examples/espidf-arduino-matter-light" + - "examples/espidf-arduino-matter-light" - "examples/arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" From 53117e04e80ec3f804fa7de42fdd7249a5746cf3 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:49:42 +0100 Subject: [PATCH 122/175] shorten include path by using prefix --- builder/frameworks/arduino.py | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index b58527f..960c36e 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -30,6 +30,7 @@ import shutil from os.path import join from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, SConscript +from platformio import fs from platformio.package.version import pepver_to_semver from platformio.project.config import ProjectConfig from platformio.package.manager.tool import ToolPackageManager @@ -55,6 +56,8 @@ extra_flags = (''.join([element for element in board.get("build.extra_flags", "" framework_reinstall = False flag_any_custom_sdkconfig = False +FRAMEWORK_LIB_DIR = platform.get_package_dir("framework-arduinoespressif32-lib") + SConscript("_embed_files.py", exports="env") flag_any_custom_sdkconfig = os.path.exists(join(platform.get_package_dir("framework-arduinoespressif32-libs"),"sdkconfig")) @@ -171,6 +174,59 @@ def check_reinstall_frwrk(): framework_reinstall = True return framework_reinstall + +FRAMEWORK_SDK_DIR = fs.to_unix_path( + os.path.join( + FRAMEWORK_LIB_DIR, + mcu, + "include", + ) +) + +IS_INTEGRATION_DUMP = env.IsIntegrationDump() + + +def is_framework_subfolder(potential_subfolder): + if not os.path.isabs(potential_subfolder): + return False + if ( + os.path.splitdrive(FRAMEWORK_SDK_DIR)[0] + != os.path.splitdrive(potential_subfolder)[0] + ): + return False + return os.path.commonpath([FRAMEWORK_SDK_DIR]) == os.path.commonpath( + [FRAMEWORK_SDK_DIR, potential_subfolder] + ) + + +def shorthen_includes(env, node): + if IS_INTEGRATION_DUMP: + # Don't shorten include paths for IDE integrations + return node + + includes = [fs.to_unix_path(inc) for inc in env.get("CPPPATH", [])] + shortened_includes = [] + generic_includes = [] + for inc in includes: + if is_framework_subfolder(inc): + shortened_includes.append( + "-iwithprefix/" + + fs.to_unix_path(os.path.relpath(inc, FRAMEWORK_SDK_DIR)) + ) + else: + generic_includes.append(inc) + + return env.Object( + node, + CPPPATH=generic_includes, + CCFLAGS=env["CCFLAGS"] + + ["-iprefix", FRAMEWORK_SDK_DIR] + + shortened_includes, + ASFLAGS=env["ASFLAGS"] + + ["-iprefix", FRAMEWORK_SDK_DIR] + + shortened_includes, + ) + def call_compile_libs(): if mcu == "esp32c2": ARDUINO_FRMWRK_C2_LIB_DIR = join(platform.get_package_dir("framework-arduinoespressif32-libs"),mcu) @@ -192,6 +248,7 @@ if flag_custom_sdkconfig == True and flag_any_custom_sdkconfig == False: call_compile_libs() if "arduino" in env.subst("$PIOFRAMEWORK") and "espidf" not in env.subst("$PIOFRAMEWORK") and env.subst("$ARDUINO_LIB_COMPILE_FLAG") in ("Inactive", "True"): + env.AddBuildMiddleware(shorthen_includes) if os.path.exists(join(platform.get_package_dir( "framework-arduinoespressif32"), "tools", "platformio-build.py")): PIO_BUILD = "platformio-build.py" From 2dfa1893ec80a0b257d84bc2de909ffc9f89b631 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:50:42 +0100 Subject: [PATCH 123/175] typo --- builder/frameworks/arduino.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 960c36e..7bf2c53 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -56,7 +56,7 @@ extra_flags = (''.join([element for element in board.get("build.extra_flags", "" framework_reinstall = False flag_any_custom_sdkconfig = False -FRAMEWORK_LIB_DIR = platform.get_package_dir("framework-arduinoespressif32-lib") +FRAMEWORK_LIB_DIR = platform.get_package_dir("framework-arduinoespressif32-libs") SConscript("_embed_files.py", exports="env") From 401c7eaf1b132722c78e7b06eec7fcc26f6d8e71 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:27:18 +0100 Subject: [PATCH 124/175] Windows shouldnt need anymore special env setup --- .github/workflows/examples.yml | 35 +++++++--------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index cf43a39..ab64b14 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -1,4 +1,4 @@ -name: Examples +name: CI Examples on: workflow_dispatch: # Manually start a workflow @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, windows-2022, macos-14] + os: [ubuntu-24.04, windows-2022, macos-15] example: - "examples/arduino-blink" - "examples/arduino-rmt-blink" @@ -22,7 +22,7 @@ jobs: - "examples/arduino-zigbee-switch" - "examples/tasmota" - "examples/espidf-arduino-h2zero-BLE_scan" - - "examples/espidf-arduino-matter-light" + #- "examples/espidf-arduino-matter-light" - "examples/arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" @@ -45,37 +45,16 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" - - name: Install Windows dependencies + python-version: "3.13" + - name: Install dependencies run: | python -m pip install --upgrade pip pip install wheel - pip install -U https://github.com/platformio/platformio/archive/develop.zip + pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.17b2.zip pio pkg install --global --platform file://. - if: "matrix.os == 'windows-2022'" - env: - PLATFORMIO_CORE_DIR: C:\plat - PLATFORMIO_PACKAGES_DIR: C:\plat\pack - PLATFORMIO_PLATFORMS_DIR: C:\plat\plat - - name: Build Windows examples - run: pio run -d ${{ matrix.example }} - if: "matrix.example != 'examples/tasmota' && matrix.os == 'windows-2022'" - env: - PLATFORMIO_CORE_DIR: C:\plat - PLATFORMIO_PACKAGES_DIR: C:\plat\pack - PLATFORMIO_PLATFORMS_DIR: C:\plat\plat - - name: Install Ubuntu Mac dependencies - run: | - python -m pip install --upgrade pip - pip install wheel - pip install -U https://github.com/platformio/platformio/archive/develop.zip - pio pkg install --global --platform file://. - if: "matrix.os != 'windows-2022'" - name: git clone Tasmota and add to examples run: | git clone -b development --depth 1 https://github.com/arendst/Tasmota.git examples/tasmota cp examples/tasmota_platformio_override.ini examples/tasmota/platformio_override.ini - if: "matrix.example == 'examples/tasmota' && matrix.os != 'windows-2022'" - - name: Build Ubuntu Mac examples + - name: Build examples run: pio run -d ${{ matrix.example }} - if: "matrix.os != 'windows-2022'" From 937ab6760f2ab67de811ee9a0978c4ec601816ce Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 18 Jan 2025 15:47:53 +0100 Subject: [PATCH 125/175] shorten include path only for windows since it hits compile performance --- builder/frameworks/arduino.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 7bf2c53..1b13628 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -26,6 +26,7 @@ import subprocess import json import semantic_version import os +import sys import shutil from os.path import join @@ -44,6 +45,7 @@ mcu = board.get("build.mcu", "esp32") board_sdkconfig = board.get("espidf.custom_sdkconfig", "") entry_custom_sdkconfig = "\n" flag_custom_sdkconfig = False +IS_WINDOWS = sys.platform.startswith("win") if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): entry_custom_sdkconfig = env.GetProjectOption("custom_sdkconfig") @@ -248,7 +250,8 @@ if flag_custom_sdkconfig == True and flag_any_custom_sdkconfig == False: call_compile_libs() if "arduino" in env.subst("$PIOFRAMEWORK") and "espidf" not in env.subst("$PIOFRAMEWORK") and env.subst("$ARDUINO_LIB_COMPILE_FLAG") in ("Inactive", "True"): - env.AddBuildMiddleware(shorthen_includes) + if IS_WINDOWS: + env.AddBuildMiddleware(shorthen_includes) if os.path.exists(join(platform.get_package_dir( "framework-arduinoespressif32"), "tools", "platformio-build.py")): PIO_BUILD = "platformio-build.py" From 62dd42c927443d42fe577f56baa7d5952f31f45c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:40:21 +0100 Subject: [PATCH 126/175] IDF 5.3.2.250120 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index ff77290..493cbf2 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241224/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250120/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From cee0973a8f32b6ad12ab4b28f8e46d9614a932a5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:55:52 +0100 Subject: [PATCH 127/175] Arduino branch master uses not actual develop libs --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 493cbf2..f530bb9 100644 --- a/platform.json +++ b/platform.json @@ -33,7 +33,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/master.zip" + "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/idf-release/v5.3.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", From 30388bdd57a369f426de9dfc28ffe20fe66bc058 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:57:12 +0100 Subject: [PATCH 128/175] Use develop libs --- platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.py b/platform.py index 58e1b53..1ce1bb4 100644 --- a/platform.py +++ b/platform.py @@ -47,7 +47,7 @@ class Espressif32Platform(PlatformBase): self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False # use latest espressif Arduino libs - URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/master/package/package_esp32_index.template.json" + URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/idf-release/v5.3/package/package_esp32_index.template.json" packjdata = requests.get(URL).json() dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url From 5aae52f91fae97d326b27fd161b459a0341be321 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 25 Jan 2025 13:34:11 +0100 Subject: [PATCH 129/175] Hybrid compile has to be default for C2 --- boards/esp32-c2-devkitm-1.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/esp32-c2-devkitm-1.json b/boards/esp32-c2-devkitm-1.json index eb3a58c..dcf2ca4 100644 --- a/boards/esp32-c2-devkitm-1.json +++ b/boards/esp32-c2-devkitm-1.json @@ -25,6 +25,11 @@ "require_upload_port": true, "speed": 460800 }, + "espidf": { + "custom_sdkconfig": [ + "CONFIG_IDF_TARGET=\"esp32c2\"" + ] + }, "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp8684/esp8684-devkitm-1/user_guide.html", "vendor": "Espressif" } From 3511adabdfd3b36b7b3cd2a405868862d7f6cec6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 25 Jan 2025 13:35:30 +0100 Subject: [PATCH 130/175] C2: Hybrid Compile use is defined in Boards manifest --- examples/arduino-blink/platformio.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index bd12d55..26bd6f1 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -31,7 +31,6 @@ platform = espressif32 framework = arduino board = esp32-c2-devkitm-1 monitor_speed = 115200 -custom_sdkconfig = 'CONFIG_IDF_TARGET="esp32c2"' custom_component_remove = espressif/esp_hosted espressif/esp_wifi_remote espressif/esp-dsp From ed1b6f5d391b12a75e49622bbd892cb7f8c1b8a1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 25 Jan 2025 14:18:57 +0100 Subject: [PATCH 131/175] Install C2 compile skeleton only when no C2 support in framework --- builder/frameworks/arduino.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 1b13628..96fbff6 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -232,8 +232,9 @@ def shorthen_includes(env, node): def call_compile_libs(): if mcu == "esp32c2": ARDUINO_FRMWRK_C2_LIB_DIR = join(platform.get_package_dir("framework-arduinoespressif32-libs"),mcu) - ARDUINO_C2_DIR = join(platform.get_package_dir("framework-arduino-c2-skeleton-lib"),mcu) - shutil.copytree(ARDUINO_C2_DIR, ARDUINO_FRMWRK_C2_LIB_DIR, dirs_exist_ok=True) + if not os.path.exists(ARDUINO_FRMWRK_C2_LIB_DIR): + ARDUINO_C2_DIR = join(platform.get_package_dir("framework-arduino-c2-skeleton-lib"),mcu) + shutil.copytree(ARDUINO_C2_DIR, ARDUINO_FRMWRK_C2_LIB_DIR, dirs_exist_ok=True) print("*** Compile Arduino IDF libs for %s ***" % env["PIOENV"]) SConscript("espidf.py") From 4e8dc5c1cf2076fc10b672016e2b56bdbeb6e201 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:29:45 +0100 Subject: [PATCH 132/175] add c2 solo1 support in readme --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a14897..8574ce8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Setup new VSCode pioarduino project. 1. Configure a platform option in platformio.ini file: -### Stable version +### Stable Arduino currently espressif Arduino 3.1.0 and IDF 5.3.2.241210 ```ini @@ -29,7 +29,7 @@ board = ... ... ``` -### Development version +### Development Arduino espressif Arduino repo branch master and latest compiled Arduino libs ```ini @@ -39,4 +39,21 @@ board = ... ... ``` +### ESP32-solo1 and ESP32-C2 Arduino support (with pioarduino only feature *Hybrid compile*) +Example configuration: + +```ini +[env:esp32solo1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-solo1 +monitor_speed = 115200 + +[env:esp32-c2-devkitm-1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-c2-devkitm-1 +monitor_speed = 115200 +``` + Looking for sponsor button? There is none. If you want to donate, please spend a litte to a charity organization. From 1691c2bec80ae957c113b02a4ebad137d3853ac0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:23:43 +0100 Subject: [PATCH 133/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8574ce8..e00b899 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ board = ... ... ``` -### ESP32-solo1 and ESP32-C2 Arduino support (with pioarduino only feature *Hybrid compile*) +### ESP32-solo1 and ESP32-C2 Arduino support (with pioarduino only feature: *Hybrid compile*) Example configuration: ```ini From b2bfffb7918ab8ce319e140a71dbb431947a71ea Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 3 Feb 2025 22:47:42 +0100 Subject: [PATCH 134/175] libesp_lcd is mem variant specific --- builder/frameworks/espidf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index d77438e..aa32f05 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -2116,6 +2116,7 @@ if "arduino" in env.get("PIOFRAMEWORK") and "espidf" not in env.get("PIOFRAMEWOR shutil.move(join(lib_dst,"libfreertos.a"),join(mem_var,"libfreertos.a")) shutil.move(join(lib_dst,"libbootloader_support.a"),join(mem_var,"libbootloader_support.a")) shutil.move(join(lib_dst,"libesp_hw_support.a"),join(mem_var,"libesp_hw_support.a")) + shutil.move(join(lib_dst,"libesp_lcd.a"),join(mem_var,"libesp_lcd.a")) shutil.copyfile(sdkconfig_h_path,join(mem_var,"include","sdkconfig.h")) if not bool(os.path.isfile(join(arduino_libs,mcu,"sdkconfig.orig"))): From be8e6d535a1d9248b327a9ef03d275300b25c010 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 5 Feb 2025 15:01:52 +0100 Subject: [PATCH 135/175] use relaxed version for cppcheck since the currently is not available on all OS --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index f530bb9..57e2d39 100644 --- a/platform.json +++ b/platform.json @@ -120,7 +120,7 @@ "tool-cppcheck": { "optional": true, "owner": "platformio", - "version": "^1.21100.241030" + "version": "~1.21100" }, "tool-clangtidy": { "optional": true, From 608fc3b5524f470c5d3d194ea29b865043f2cdec Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 6 Feb 2025 21:24:48 +0100 Subject: [PATCH 136/175] Update cmake v3.30.2 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 57e2d39..9042e29 100644 --- a/platform.json +++ b/platform.json @@ -135,7 +135,7 @@ "tool-cmake": { "optional": true, "owner": "platformio", - "version": "~3.21.0" + "version": "~3.30.2" }, "tool-ninja": { "optional": true, From 552a0b8928404f6b28e2d5795e8237e9300c4fc4 Mon Sep 17 00:00:00 2001 From: sillyfrog <816454+sillyfrog@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:32:50 +1000 Subject: [PATCH 137/175] Add WEMOS LOLIN S3 Mini Pro board (#114) * Add WEMOS LOLIN S3 Mini Pro board * Address comments and update S3 Mini --------- Co-authored-by: Sillyfrog --- boards/lolin_s3_mini.json | 4 +-- boards/lolin_s3_mini_pro.json | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 boards/lolin_s3_mini_pro.json diff --git a/boards/lolin_s3_mini.json b/boards/lolin_s3_mini.json index 7f55f0b..c68309a 100644 --- a/boards/lolin_s3_mini.json +++ b/boards/lolin_s3_mini.json @@ -1,18 +1,18 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "memory_type": "qio_qspi" }, "core": "esp32", "extra_flags": [ "-DBOARD_HAS_PSRAM", "-DARDUINO_LOLIN_S3_MINI", - "-DARDUINO_USB_MODE=1" + "-DARDUINO_USB_CDC_ON_BOOT=1" ], "f_cpu": "240000000L", "f_flash": "80000000L", "flash_mode": "qio", + "psram_type" : "qio", "hwids": [ [ "0x303A", diff --git a/boards/lolin_s3_mini_pro.json b/boards/lolin_s3_mini_pro.json new file mode 100644 index 0000000..3afcb49 --- /dev/null +++ b/boards/lolin_s3_mini_pro.json @@ -0,0 +1,47 @@ +{ + "build": { + "arduino": { + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_LOLIN_S3_MINI_PRO", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type" : "qio", + "hwids": [ + [ + "0x303A", + "0x8167" + ] + ], + "mcu": "esp32s3", + "variant": "lolin_s3_mini_pro" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "WEMOS LOLIN S3 Mini Pro", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.wemos.cc/en/latest/s3/index.html", + "vendor": "WEMOS" +} + \ No newline at end of file From 70952b3987c840ed8899fa331166abf00891dc6f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 13 Feb 2025 14:57:16 +0100 Subject: [PATCH 138/175] Update platformio.ini --- examples/arduino-matter-light/platformio.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/arduino-matter-light/platformio.ini b/examples/arduino-matter-light/platformio.ini index 9c624da..fca1f7a 100644 --- a/examples/arduino-matter-light/platformio.ini +++ b/examples/arduino-matter-light/platformio.ini @@ -12,6 +12,5 @@ platform = espressif32 framework = arduino board_build.partitions = huge_app.csv -build_flags = -DCHIP_HAVE_CONFIG_H board = esp32-c6-devkitc-1 monitor_speed = 115200 From 3a5755e140e66366e64d7f719d0f56ee9dd1b897 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:01:04 +0100 Subject: [PATCH 139/175] back to branch master --- platform.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.json b/platform.json index 9042e29..3995ab6 100644 --- a/platform.json +++ b/platform.json @@ -33,7 +33,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/idf-release/v5.3.zip" + "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/master.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250120/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250212/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From d9e8657e5fee4bc956a39440a35b79702c7d2ee9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:02:06 +0100 Subject: [PATCH 140/175] Use branch master for libs --- platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.py b/platform.py index 1ce1bb4..58e1b53 100644 --- a/platform.py +++ b/platform.py @@ -47,7 +47,7 @@ class Espressif32Platform(PlatformBase): self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False # use latest espressif Arduino libs - URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/idf-release/v5.3/package/package_esp32_index.template.json" + URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/master/package/package_esp32_index.template.json" packjdata = requests.get(URL).json() dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url From d68cb0e870fc5e4d11bf1abe72bd5648e6708df7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:04:42 +0100 Subject: [PATCH 141/175] fix IDF path --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 3995ab6..0eeb4fc 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250212/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250210/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From d748c6513d5808cf1c11d4e2cc244fcef9074905 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:06:21 +0100 Subject: [PATCH 142/175] Platform 53.03.12+develop --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 0eeb4fc..f986af4 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "53.03.10+develop", + "version": "53.03.12+develop", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" From 6c1ba0234a5342ee9a3ebafee76b606b327927e5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 21 Feb 2025 22:13:07 +0100 Subject: [PATCH 143/175] Update development branch to Arduino core 3.2.x --- builder/frameworks/ulp.py | 2 ++ platform.json | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index 7965df1..7afa2ef 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -99,6 +99,7 @@ def generate_ulp_config(target_config): cmd = ( os.path.join(platform.get_package_dir("tool-cmake"), "bin", "cmake"), + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "-DCMAKE_GENERATOR=Ninja", "-DCMAKE_TOOLCHAIN_FILE=" + os.path.join( @@ -117,6 +118,7 @@ def generate_ulp_config(target_config): "-DSDKCONFIG_HEADER=" + os.path.join(BUILD_DIR, "config", "sdkconfig.h"), "-DPYTHON=" + env.subst("$PYTHONEXE"), "-DSDKCONFIG_CMAKE=" + os.path.join(BUILD_DIR, "config", "sdkconfig.cmake"), + "-DCMAKE_MODULE_PATH=" + fs.to_unix_path(os.path.join(FRAMEWORK_DIR, "components", "ulp", "cmake")), "-GNinja", "-B", ULP_BUILD_DIR, diff --git a/platform.json b/platform.json index f986af4..d748bdd 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "53.03.12+develop", + "version": "54.03.20+develop", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -33,7 +33,7 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/refs/heads/master.zip" + "version": "https://github.com/espressif/arduino-esp32/archive/master.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", @@ -51,19 +51,19 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250210/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250218/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", "optional": true, "owner": "platformio", - "version": "13.2.0+20240530" + "version": "14.2.0+20241119" }, "toolchain-riscv32-esp": { "type": "toolchain", "optional": true, "owner": "platformio", - "version": "13.2.0+20240530" + "version": "14.2.0+20241119" }, "toolchain-esp32ulp": { "type": "toolchain", From 21a53207c5ec832341758fe8d12e73b6e5e825a4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:40:13 +0100 Subject: [PATCH 144/175] Update IDF v5.4.0.250221 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index d748bdd..79c5cb1 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250218/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250221/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 4c85ff44e57cefddd06034737f05f4c9021bfafb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:46:57 +0100 Subject: [PATCH 145/175] Revert to IDF v5.4.0.250218 until the reason for failing in `kconfiglib.py` with latest IDF 5.4.0.250221 is found --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 79c5cb1..d748bdd 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250221/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250218/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From de3de5a5d1905d98f82ae950c31b83332235f00e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:15:19 +0100 Subject: [PATCH 146/175] Update espidf pip dependencies --- builder/frameworks/espidf.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index aa32f05..77c7f14 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1530,12 +1530,12 @@ def install_python_deps(): # https://github.com/platformio/platformio-core/issues/4614 "urllib3": "<2", # https://github.com/platformio/platform-espressif32/issues/635 - "cryptography": "~=41.0.1" if IDF5 else ">=2.1.4,<35.0.0", + "cryptography": "~=41.0.1", "future": ">=0.18.3", - "pyparsing": ">=3.1.0,<4" if IDF5 else ">=2.0.3,<2.4.0", - "kconfiglib": "~=14.1.0" if IDF5 else "~=13.7.1", - "idf-component-manager": "~=2.0.1" if IDF5 else "~=1.0", - "esp-idf-kconfig": ">=1.4.2,<2.0.0" + "pyparsing": ">=3.1.0,<4", + "kconfiglib": "~=14.1.0", + "idf-component-manager": "~=2.0.1", + "esp-idf-kconfig": ">=2.5.0" } if sys_platform.system() == "Darwin" and "arm" in sys_platform.machine().lower(): From 81779804b5fc68b4b7863a3a631337248ef4edaa Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:37:27 +0100 Subject: [PATCH 147/175] Update IDF v5.4.0.250221 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index d748bdd..79c5cb1 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250218/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250221/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 00628a99cf426d84201281e21fb59cdee6213f0a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:27:14 +0100 Subject: [PATCH 148/175] kconfiglib from pypi not needed --- builder/frameworks/espidf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 77c7f14..c6a1d3d 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1533,7 +1533,6 @@ def install_python_deps(): "cryptography": "~=41.0.1", "future": ">=0.18.3", "pyparsing": ">=3.1.0,<4", - "kconfiglib": "~=14.1.0", "idf-component-manager": "~=2.0.1", "esp-idf-kconfig": ">=2.5.0" } From f6ce6a9ea60f4b54d6ff2edb03cf2c80419aee6f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:28:31 +0100 Subject: [PATCH 149/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e00b899..c5e4f17 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pioarduino (p)eople (i)nitiated (o)ptimized (arduino) -[![Build Status](https://github.com/pioarduino/platform-espressif32/workflows/Examples/badge.svg)](https://github.com/pioarduino/platform-espressif32/actions) +[![Examples](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml/badge.svg)](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml) [![Discord](https://img.shields.io/discord/1263397951829708871.svg?logo=discord&logoColor=white&color=5865F2&label=Discord)](https://discord.gg/Nutz9crnZr) [![GitHub Releases](https://img.shields.io/github/downloads/pioarduino/platform-espressif32/total?label=downloads)](https://github.com/pioarduino/platform-espressif32/releases/latest) From 1ee4cc65d6f6bb0b7923bb0a51f61d0328436ebb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:35:32 +0100 Subject: [PATCH 150/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5e4f17..42f6463 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pioarduino (p)eople (i)nitiated (o)ptimized (arduino) -[![Examples](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml/badge.svg)](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml) +[![CI Examples](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml/badge.svg?branch=develop)](https://github.com/pioarduino/platform-espressif32/actions/workflows/examples.yml) [![Discord](https://img.shields.io/discord/1263397951829708871.svg?logo=discord&logoColor=white&color=5865F2&label=Discord)](https://discord.gg/Nutz9crnZr) [![GitHub Releases](https://img.shields.io/github/downloads/pioarduino/platform-espressif32/total?label=downloads)](https://github.com/pioarduino/platform-espressif32/releases/latest) From f2ddfd62307141eb2ae7db3819d2a8f52c2f6608 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:39:07 +0100 Subject: [PATCH 151/175] Upcoming release will be IDF 54 based --- .github/workflows/release_zips.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_zips.yml b/.github/workflows/release_zips.yml index 5f25ce2..a3d12f2 100644 --- a/.github/workflows/release_zips.yml +++ b/.github/workflows/release_zips.yml @@ -3,7 +3,7 @@ name: Create zip file with recursive source clone for release on: push: tags: - - 53* + - 54* jobs: release_zips: From 5b57f8f51e42777ec6cceb58f7a19b42db8bea0b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:30:54 +0100 Subject: [PATCH 152/175] Use pioarduino core v6.1.17 --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index ab64b14..eef99c0 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -50,7 +50,7 @@ jobs: run: | python -m pip install --upgrade pip pip install wheel - pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.17b2.zip + pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.17.zip pio pkg install --global --platform file://. - name: git clone Tasmota and add to examples run: | From aedf0b42e57bde499fd7dd2b78b6d7b44940c37a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:04:11 +0100 Subject: [PATCH 153/175] ppioarduino esptool.py v4.8.8 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 79c5cb1..3bb195d 100644 --- a/platform.json +++ b/platform.json @@ -86,7 +86,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.6/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.8/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", From 33a8925ca14f22bef1d5901252caeee424c5ebd6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:02:58 +0100 Subject: [PATCH 154/175] add "rich-click": ">=1.8.6" dependency --- builder/frameworks/arduino.py | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 96fbff6..cbf32e4 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -101,6 +101,7 @@ def install_python_deps(): deps = { "wheel": ">=0.35.1", + "rich-click": ">=1.8.6", "PyYAML": ">=6.0.2", "intelhex": ">=2.3.0" } From 639c722603fa855e0404e5adfef99e02ce3b7562 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:03:35 +0100 Subject: [PATCH 155/175] add "rich-click": ">=1.8.6" dependency --- builder/frameworks/espidf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index c6a1d3d..75e133e 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -82,6 +82,7 @@ def install_standard_python_deps(): deps = { "wheel": ">=0.35.1", + "rich-click": ">=1.8.6", "PyYAML": ">=6.0.2" } From b343490a6c659e074397bb1456d92345f2f0f80a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Feb 2025 18:17:11 +0100 Subject: [PATCH 156/175] remove hybrid compile file leftovers --- builder/frameworks/espidf.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 75e133e..b77b733 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -2123,6 +2123,11 @@ if "arduino" in env.get("PIOFRAMEWORK") and "espidf" not in env.get("PIOFRAMEWOR shutil.move(join(arduino_libs,mcu,"sdkconfig"),join(arduino_libs,mcu,"sdkconfig.orig")) shutil.copyfile(join(env.subst("$PROJECT_DIR"),"sdkconfig."+env["PIOENV"]),join(arduino_libs,mcu,"sdkconfig")) shutil.copyfile(join(env.subst("$PROJECT_DIR"),"sdkconfig."+env["PIOENV"]),join(arduino_libs,"sdkconfig")) + try: + os.remove(join(env.subst("$PROJECT_DIR"),"dependencies.lock")) + os.remove(join(env.subst("$PROJECT_DIR"),"CMakeLists.txt")) + except: + pass print("*** Copied compiled %s IDF libraries to Arduino framework ***" % idf_variant) pio_exe_path = shutil.which("platformio"+(".exe" if IS_WINDOWS else "")) From 1246d6958622d1f3f77dd9d68a2496ad2b5f383a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Feb 2025 18:38:21 +0100 Subject: [PATCH 157/175] reinstall Arduino framework too --- builder/frameworks/arduino.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index cbf32e4..4c2bd93 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -240,9 +240,12 @@ def call_compile_libs(): SConscript("espidf.py") if check_reinstall_frwrk() == True: - print("*** Reinstall Arduino framework libs ***") + print("*** Reinstall Arduino framework ***") + shutil.rmtree(platform.get_package_dir("framework-arduinoespressif32")) shutil.rmtree(platform.get_package_dir("framework-arduinoespressif32-libs")) + ARDUINO_FRMWRK_URL = str(platform.get_package_spec("framework-arduinoespressif32")).split("uri=",1)[1][:-1] ARDUINO_FRMWRK_LIB_URL = str(platform.get_package_spec("framework-arduinoespressif32-libs")).split("uri=",1)[1][:-1] + pm.install(ARDUINO_FRMWRK_URL) pm.install(ARDUINO_FRMWRK_LIB_URL) if flag_custom_sdkconfig == True: call_compile_libs() From 5711fcafa4670fc5e238132bd063f986fdfd1e12 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:19:26 +0100 Subject: [PATCH 158/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42f6463..3867dcc 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with ## IDE Preparation -- [Download and install official Microsoft Visual Studio Code](https://code.visualstudio.com/). pioarduino IDE is built on top of it. +- [Download and install Microsoft Visual Studio Code](https://code.visualstudio.com/). pioarduino IDE is on top of it. - Open the extension manager. - Search for the `pioarduino ide` extension. - Install pioarduino IDE extension. From 6fa2efbb2b847d655ff4c8703ce484f91d7e98a9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:43:45 +0100 Subject: [PATCH 159/175] Update IDF 5.4.0.250303 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 3bb195d..e252251 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250221/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250303/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From aa5a97e52d54f9bc133a697ab1b176c7d3ff1f25 Mon Sep 17 00:00:00 2001 From: Unexpected Maker Date: Mon, 10 Mar 2025 21:35:13 +1100 Subject: [PATCH 160/175] Added missing UM boards and fixed TinyS3 product URL. (#122) * Added missing UM boards and fixed TinyS3 product URL. Signed-off-by: Seon Rozenblum * More modifications for UM boards. Signed-off-by: Seon Rozenblum --------- Signed-off-by: Seon Rozenblum Co-authored-by: Seon Rozenblum --- boards/um_bling.json | 51 ++++++++++++++++++++++++++++++++++++ boards/um_feathers3.json | 2 +- boards/um_feathers3_neo.json | 51 ++++++++++++++++++++++++++++++++++++ boards/um_nanos3.json | 2 +- boards/um_omgs3.json | 51 ++++++++++++++++++++++++++++++++++++ boards/um_pros3.json | 2 +- boards/um_tinyc6.json | 38 +++++++++++++++++++++++++++ boards/um_tinys2.json | 3 ++- boards/um_tinys3.json | 4 +-- 9 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 boards/um_bling.json create mode 100644 boards/um_feathers3_neo.json create mode 100644 boards/um_omgs3.json create mode 100644 boards/um_tinyc6.json diff --git a/boards/um_bling.json b/boards/um_bling.json new file mode 100644 index 0000000..aeeabad --- /dev/null +++ b/boards/um_bling.json @@ -0,0 +1,51 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_BLING", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0X303A", + "0x817F" + ] + ], + "mcu": "esp32s3", + "variant": "um_bling" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Unexpected Maker BLING!", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://unexpectedmaker.com/shop/bling", + "vendor": "Unexpected Maker" +} diff --git a/boards/um_feathers3.json b/boards/um_feathers3.json index 1a851fa..9c39ea9 100644 --- a/boards/um_feathers3.json +++ b/boards/um_feathers3.json @@ -1,7 +1,6 @@ { "build": { "arduino":{ - "ldscript": "esp32s3_out.ld", "partitions": "default_16MB.csv", "memory_type": "qio_qspi" }, @@ -10,6 +9,7 @@ "-DARDUINO_FEATHERS3", "-DBOARD_HAS_PSRAM", "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", "-DARDUINO_EVENT_RUNNING_CORE=1" ], diff --git a/boards/um_feathers3_neo.json b/boards/um_feathers3_neo.json new file mode 100644 index 0000000..0849ee3 --- /dev/null +++ b/boards/um_feathers3_neo.json @@ -0,0 +1,51 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_FEATHERS3NEO", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0X303A", + "0x81FB" + ] + ], + "mcu": "esp32s3", + "variant": "um_feathers3neo" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Unexpected Maker FeatherS3 Neo", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://unexpectedmaker.com/shop/feathers3neo", + "vendor": "Unexpected Maker" +} diff --git a/boards/um_nanos3.json b/boards/um_nanos3.json index 921a36e..742c0ac 100644 --- a/boards/um_nanos3.json +++ b/boards/um_nanos3.json @@ -1,7 +1,6 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "partitions": "default_8MB.csv", "memory_type": "qio_qspi" }, @@ -10,6 +9,7 @@ "-DBOARD_HAS_PSRAM", "-DARDUINO_NANOS3", "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", "-DARDUINO_EVENT_RUNNING_CORE=1" ], diff --git a/boards/um_omgs3.json b/boards/um_omgs3.json new file mode 100644 index 0000000..55994d4 --- /dev/null +++ b/boards/um_omgs3.json @@ -0,0 +1,51 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_OMGS3", + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0X303A", + "0x8224" + ] + ], + "mcu": "esp32s3", + "variant": "um_omgs3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Unexpected Maker OMGS3", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://unexpectedmaker.com/shop/omgs3", + "vendor": "Unexpected Maker" +} diff --git a/boards/um_pros3.json b/boards/um_pros3.json index 8edcefa..484c024 100644 --- a/boards/um_pros3.json +++ b/boards/um_pros3.json @@ -1,7 +1,6 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "partitions": "default_16MB.csv", "memory_type": "qio_qspi" }, @@ -10,6 +9,7 @@ "-DARDUINO_PROS3", "-DBOARD_HAS_PSRAM", "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", "-DARDUINO_EVENT_RUNNING_CORE=1" ], diff --git a/boards/um_tinyc6.json b/boards/um_tinyc6.json new file mode 100644 index 0000000..f34eee9 --- /dev/null +++ b/boards/um_tinyc6.json @@ -0,0 +1,38 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_TINYC6" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "um_tinyc6" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Unexpected Maker TinyC6", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://unexpectedmaker.com/shop/tinyc6", + "vendor": "Unexpected Maker" +} diff --git a/boards/um_tinys2.json b/boards/um_tinys2.json index 8a57216..7ca5ca4 100644 --- a/boards/um_tinys2.json +++ b/boards/um_tinys2.json @@ -1,7 +1,8 @@ { "build": { "arduino": { - "ldscript": "esp32s2_out.ld" + "partitions": "default_4MB.csv", + "memory_type": "qio_qspi" }, "core": "esp32", "extra_flags": [ diff --git a/boards/um_tinys3.json b/boards/um_tinys3.json index ed7b2a0..cac1514 100644 --- a/boards/um_tinys3.json +++ b/boards/um_tinys3.json @@ -1,7 +1,6 @@ { "build": { "arduino":{ - "ldscript": "esp32s3_out.ld", "partitions": "default_8MB.csv", "memory_type": "qio_qspi" }, @@ -10,6 +9,7 @@ "-DARDUINO_TINYS3", "-DBOARD_HAS_PSRAM", "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", "-DARDUINO_EVENT_RUNNING_CORE=1" ], @@ -46,6 +46,6 @@ "require_upload_port": true, "speed": 460800 }, - "url": "https://unexpectedmaker.com/shop/ttinys3-esp32s3", + "url": "https://unexpectedmaker.com/shop/tinys3", "vendor": "Unexpected Maker" } From e247f2ed0c2df6453d9618d514841c2d75cafede Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:52:12 +0100 Subject: [PATCH 161/175] boards update taken from https://github.com/sivar2311/platformio_boards Thx @sivar2311 --- boards/bpi-centi-s3.json | 52 ++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n16r16.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n16r2.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n16r8.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n4r2.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n4r8.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n8r2.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-devkitc1-n8r8.json | 55 +++++++++++++++++++++++++ boards/esp32-s3-fh4r2.json | 56 ++++++++++++++++++++++++++ boards/feenove-esp32-s3-n8r8.json | 55 +++++++++++++++++++++++++ boards/nologo_esp32c3_super_mini.json | 32 +++++++++++++++ boards/sparkfun_pro_micro_esp32c3.json | 36 +++++++++++++++++ 12 files changed, 616 insertions(+) create mode 100644 boards/bpi-centi-s3.json create mode 100644 boards/esp32-s3-devkitc1-n16r16.json create mode 100644 boards/esp32-s3-devkitc1-n16r2.json create mode 100644 boards/esp32-s3-devkitc1-n16r8.json create mode 100644 boards/esp32-s3-devkitc1-n4r2.json create mode 100644 boards/esp32-s3-devkitc1-n4r8.json create mode 100644 boards/esp32-s3-devkitc1-n8r2.json create mode 100644 boards/esp32-s3-devkitc1-n8r8.json create mode 100644 boards/esp32-s3-fh4r2.json create mode 100644 boards/feenove-esp32-s3-n8r8.json create mode 100644 boards/nologo_esp32c3_super_mini.json create mode 100644 boards/sparkfun_pro_micro_esp32c3.json diff --git a/boards/bpi-centi-s3.json b/boards/bpi-centi-s3.json new file mode 100644 index 0000000..01c9509 --- /dev/null +++ b/boards/bpi-centi-s3.json @@ -0,0 +1,52 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_BPI_CENTI_S3", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x80DF" + ] + ], + "mcu": "esp32s3", + "variant": "bpi_leaf_s3" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms" : [ + "espressif32" + ], + "name": "BPI-Centi-S3", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://wiki.banana-pi.org/BPI-Leaf-S3", + "vendor": "BPI Tech" +} diff --git a/boards/esp32-s3-devkitc1-n16r16.json b/boards/esp32-s3-devkitc1-n16r16.json new file mode 100644 index 0000000..99c7113 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n16r16.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_16MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB Flash Quad, 16 MB PSRAM Octal)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n16r2.json b/boards/esp32-s3-devkitc1-n16r2.json new file mode 100644 index 0000000..08968e5 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n16r2.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_16MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N8R8 (16 MB Flash Quad, 2 MB PSRAM Quad)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n16r8.json b/boards/esp32-s3-devkitc1-n16r8.json new file mode 100644 index 0000000..1c7e5d6 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n16r8.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_16MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB Flash Quad, 8 MB PSRAM Octal)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n4r2.json b/boards/esp32-s3-devkitc1-n4r2.json new file mode 100644 index 0000000..1ed4a33 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n4r2.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_4MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N8R8 (4 MB Flash Quad, 2 MB PSRAM Quad)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n4r8.json b/boards/esp32-s3-devkitc1-n4r8.json new file mode 100644 index 0000000..338fee2 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n4r8.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_4MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N8R8 (4 MB Flash Quad, 8 MB PSRAM Octal)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n8r2.json b/boards/esp32-s3-devkitc1-n8r2.json new file mode 100644 index 0000000..46e2a89 --- /dev/null +++ b/boards/esp32-s3-devkitc1-n8r2.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N8R8 (8 MB Flash Quad, 2 MB PSRAM quad)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-devkitc1-n8r8.json b/boards/esp32-s3-devkitc1-n8r8.json new file mode 100644 index 0000000..6284c7c --- /dev/null +++ b/boards/esp32-s3-devkitc1-n8r8.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N8R8 (8 MB Flash Quad, 8 MB PSRAM Octal)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} \ No newline at end of file diff --git a/boards/esp32-s3-fh4r2.json b/boards/esp32-s3-fh4r2.json new file mode 100644 index 0000000..1333a31 --- /dev/null +++ b/boards/esp32-s3-fh4r2.json @@ -0,0 +1,56 @@ +{ + "build": { + "arduino":{ + "partitions": "default.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms" : [ + "espressif32" + ], + "name": "Espressif ESP32-S3-FH4R2 (4 MB QD, 2MB PSRAM)", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" + } \ No newline at end of file diff --git a/boards/feenove-esp32-s3-n8r8.json b/boards/feenove-esp32-s3-n8r8.json new file mode 100644 index 0000000..0c508d5 --- /dev/null +++ b/boards/feenove-esp32-s3-n8r8.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "partitions": "default_8MB.csv", + "memory_type": "dio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "psram_type": "opi", + "hwids": [ + [ + "0X303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms" : [ + "espressif32" + ], + "name": "Freenove ESP32-S3 WROOM N8R8 (8MB Flash / 8MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board", + "vendor": "Freenove" +} diff --git a/boards/nologo_esp32c3_super_mini.json b/boards/nologo_esp32c3_super_mini.json new file mode 100644 index 0000000..e8e302c --- /dev/null +++ b/boards/nologo_esp32c3_super_mini.json @@ -0,0 +1,32 @@ +{ + "build": { + "core": "esp32", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "extra_flags": "-DARDUINO_ESP32C3_DEV -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1", + "mcu": "esp32c3", + "variant": "nologo_esp32c3_super_mini" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Nologo ESP32C3 SuperMini", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.nologo.tech/product/esp32/esp32c3/esp32c3supermini/esp32C3SuperMini.html", + "vendor": "Nologo" +} \ No newline at end of file diff --git a/boards/sparkfun_pro_micro_esp32c3.json b/boards/sparkfun_pro_micro_esp32c3.json new file mode 100644 index 0000000..e31d53f --- /dev/null +++ b/boards/sparkfun_pro_micro_esp32c3.json @@ -0,0 +1,36 @@ +{ + "build": { + "core": "esp32", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "extra_flags": [ + "-DSPARKFUN_PRO_MICRO_ESP32C3", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "mcu": "esp32c3", + "variant": "sparkfun_pro_micro_esp32c3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "SparkFun Pro Micro ESP32-C3", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.sparkfun.com/sparkfun-pro-micro-esp32-c3.html", + "vendor": "Sparkfun" +} \ No newline at end of file From 832a1953cf9de217ee667d80cb7d514db5979d76 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 19 Mar 2025 17:25:35 +0100 Subject: [PATCH 162/175] pioarduino core 6.1.18 --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index eef99c0..c77c208 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -50,7 +50,7 @@ jobs: run: | python -m pip install --upgrade pip pip install wheel - pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.17.zip + pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip pio pkg install --global --platform file://. - name: git clone Tasmota and add to examples run: | From cac1250f4001e54aabc4443b4960bccca5189be0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 19 Mar 2025 17:41:05 +0100 Subject: [PATCH 163/175] Update IDF 5.4.0.250314 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index e252251..6c3b544 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250303/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250314/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From 60b296341d54672ec4c3d06cdf50e61ce24ad4f9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:34:39 +0100 Subject: [PATCH 164/175] Create esp32-s3-devkitc-1-n32r8v.json --- boards/esp32-s3-devkitc-1-n32r8v.json | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 boards/esp32-s3-devkitc-1-n32r8v.json diff --git a/boards/esp32-s3-devkitc-1-n32r8v.json b/boards/esp32-s3-devkitc-1-n32r8v.json new file mode 100644 index 0000000..39d725a --- /dev/null +++ b/boards/esp32-s3-devkitc-1-n32r8v.json @@ -0,0 +1,52 @@ +{ + "build": { + "arduino":{ + "partitions": "default_32MB.csv", + "memory_type": "opi_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "opi", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-S3-DevKitC-1-N32R8V (32 MB Flash Octal, 8 MB PSRAM Octal)", + "upload": { + "flash_size": "32MB", + "maximum_ram_size": 327680, + "maximum_size": 33554432, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} From b2c4121858d5f800bb8de740e027f4f489168f90 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 21 Mar 2025 12:26:43 +0100 Subject: [PATCH 165/175] Board Arduino Nano: standard no remapping causes more issues than it solves. --- boards/arduino_nano_esp32.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arduino_nano_esp32.json b/boards/arduino_nano_esp32.json index e1bf757..1bec891 100644 --- a/boards/arduino_nano_esp32.json +++ b/boards/arduino_nano_esp32.json @@ -8,7 +8,7 @@ "core": "esp32", "extra_flags": [ "-DARDUINO_NANO_ESP32", - "-DBOARD_HAS_PIN_REMAP", + "-DBOARD_USES_HW_GPIO_NUMBERS", "-DBOARD_HAS_PSRAM", "-DUSB_MANUFACTURER=\\\"Arduino\\\"", "-DUSB_PRODUCT=\\\"NanoESP32\\\"", From 0a48460db9d434e47df077d60811f35be16d4fc5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 21 Mar 2025 12:27:10 +0100 Subject: [PATCH 166/175] Update arduino_nano_esp32.json --- boards/arduino_nano_esp32.json | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arduino_nano_esp32.json b/boards/arduino_nano_esp32.json index 1bec891..737d194 100644 --- a/boards/arduino_nano_esp32.json +++ b/boards/arduino_nano_esp32.json @@ -1,7 +1,6 @@ { "build": { "arduino":{ - "ldscript": "esp32s3_out.ld", "partitions": "app3M_fat9M_fact512k_16MB.csv", "memory_type": "qio_opi" }, From 3d5ca253cae2c7472571e8cc3101f59de1644679 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 21 Mar 2025 12:55:44 +0100 Subject: [PATCH 167/175] add arduino_nano_esp32 board to Arduino Blink example --- examples/arduino-blink/platformio.ini | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index 26bd6f1..a6f6196 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -44,6 +44,25 @@ custom_component_remove = espressif/esp_hosted espressif/esp_rainmaker espressif/rmaker_common +[env:esp32-s3-arduino_nano_esp32] +platform = espressif32 +framework = arduino +board = arduino_nano_esp32 +build_flags = -DLED_BUILTIN=48 +monitor_speed = 115200 +custom_component_remove = espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/esp32-camera + espressif/libsodium + espressif/esp-modbus + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/rmaker_common + [env:esp32s3-qio_opi_per] ; OPI Performance settings -> Display use platform = espressif32 From 2fa97a5f95524b787c4142b85e301508b1c10bc2 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 21 Mar 2025 13:13:56 +0100 Subject: [PATCH 168/175] remove already defined --- examples/arduino-blink/platformio.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index a6f6196..8fe2201 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -48,7 +48,6 @@ custom_component_remove = espressif/esp_hosted platform = espressif32 framework = arduino board = arduino_nano_esp32 -build_flags = -DLED_BUILTIN=48 monitor_speed = 115200 custom_component_remove = espressif/esp_hosted espressif/esp_wifi_remote From 9c5cf8becd14e864b183aa82cd8f1b172a0a3725 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:56:21 +0100 Subject: [PATCH 169/175] no Arduino Nora Nano support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3867dcc..e551513 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and Bluetooth. ESP32 integrates an antenna switch, RF balun, power amplifier, low-noise receive amplifier, filters, and power management modules. * Issues with boards (wrong / missing). All issues caused from boards will not be fixed from the maintainer(s). A PR needs to be provided against branch `develop` to solve. - +* No support for the Arduino Nora Nano board, issues needs to be solved by the community ## IDE Preparation - [Download and install Microsoft Visual Studio Code](https://code.visualstudio.com/). pioarduino IDE is on top of it. From 10aa2177010c048096437cbba829a42f9c4a50bc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 24 Mar 2025 12:42:38 +0100 Subject: [PATCH 170/175] arduino_nano_esp32.json: flash recovery image --- boards/arduino_nano_esp32.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boards/arduino_nano_esp32.json b/boards/arduino_nano_esp32.json index 737d194..4d72679 100644 --- a/boards/arduino_nano_esp32.json +++ b/boards/arduino_nano_esp32.json @@ -41,6 +41,14 @@ ], "name": "Arduino Nano ESP32", "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0xf70000", + "variants/arduino_nano_nora/extra/nora_recovery/nora_recovery.ino.bin" + ] + ] + }, "flash_size": "16MB", "maximum_ram_size": 327680, "maximum_size": 16777216, From 2f4d5d03ef84210f972fff44eb65d7e6a981144d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:09:55 +0100 Subject: [PATCH 171/175] Update platform.json --- platform.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform.json b/platform.json index 6c3b544..2a4127a 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "54.03.20+develop", + "version": "54.03.20", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -33,13 +33,13 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/archive/master.zip" + "version": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esp32-3.2.0.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", "optional": true, "owner": "espressif", - "version": "" + "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-2f7dcd86-v1.zip" }, "framework-arduino-c2-skeleton-lib": { "type": "framework", From dffe2c49f401752412b568f629cc5cd93d2dad3f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:10:55 +0100 Subject: [PATCH 172/175] Arduino core 3.2.0 --- platform.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/platform.py b/platform.py index 58e1b53..e1b3273 100644 --- a/platform.py +++ b/platform.py @@ -46,11 +46,6 @@ class Espressif32Platform(PlatformBase): if "arduino" in frameworks: self.packages["framework-arduinoespressif32"]["optional"] = False self.packages["framework-arduinoespressif32-libs"]["optional"] = False - # use latest espressif Arduino libs - URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/master/package/package_esp32_index.template.json" - packjdata = requests.get(URL).json() - dyn_lib_url = packjdata['packages'][0]['tools'][0]['systems'][0]['url'] - self.packages["framework-arduinoespressif32-libs"]["version"] = dyn_lib_url if variables.get("custom_sdkconfig") is not None or len(str(board_sdkconfig)) > 3: frameworks.append("espidf") From 7cb7d1824f9470bf32e12ed4a3872dba82d66961 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:15:19 +0100 Subject: [PATCH 173/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e551513..3a98684 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Configure a platform option in platformio.ini file: ### Stable Arduino -currently espressif Arduino 3.1.0 and IDF 5.3.2.241210 +currently espressif Arduino 3.2.0 and IDF 5.4.0.250327 ```ini [env:stable] From 500e59336fbb96b734e565bc328075b72fe0be9f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:19:03 +0100 Subject: [PATCH 174/175] Update IDF v5.4.0.250327 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 2a4127a..02d05fc 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250314/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250327/esp-idf-v5.4.0.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", From c6f1f4164d16dae8fda13221eb0f2722429175c6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:47:01 +0100 Subject: [PATCH 175/175] Update IDF 5.4.1 release --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 02d05fc..beaab0e 100644 --- a/platform.json +++ b/platform.json @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.0.250327/esp-idf-v5.4.0.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.4.1/esp-idf-v5.4.1.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain",