From 49c410b01be9d748c28f5c168d982a1a1f0e131b Mon Sep 17 00:00:00 2001 From: Peter M Date: Tue, 20 Jan 2026 00:55:45 +0100 Subject: [PATCH 1/2] Fix ESP32 deep_sleep hold Supercedes: https://github.com/atomvm/AtomVM/pull/2063 CI: Only test release-v5.4 and 5.5.2 for ESP32P4, due to their support for both P4 revisions. Changelog fixes and additions. Other minor fixes related to CI. Signed-off-by: Peter M --- .github/workflows/esp32-build.yaml | 14 +++---- .github/workflows/esp32-simtest.yaml | 4 +- CHANGELOG.md | 3 +- .../components/avm_builtins/gpio_driver.c | 6 +-- .../test/main/test_erl_sources/CMakeLists.txt | 2 + .../test_erl_sources/test_deep_sleep_hold.erl | 41 +++++++++++++++++++ src/platforms/esp32/test/main/test_main.c | 8 +++- 7 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 src/platforms/esp32/test/main/test_erl_sources/test_deep_sleep_hold.erl diff --git a/.github/workflows/esp32-build.yaml b/.github/workflows/esp32-build.yaml index 173d9a6dc4..488282bd44 100644 --- a/.github/workflows/esp32-build.yaml +++ b/.github/workflows/esp32-build.yaml @@ -45,8 +45,7 @@ jobs: fail-fast: false matrix: - esp-idf-target: ["esp32", "esp32c3", "esp32p4"] - language: ['cpp'] + esp-idf-target: ["esp32", "esp32c3"] idf-version: - 'v5.1.6' - 'v5.2.6' @@ -57,10 +56,11 @@ jobs: exclude: - esp-idf-target: "esp32c3" idf-version: 'v5.1.6' + include: - esp-idf-target: "esp32p4" - idf-version: 'v5.1.6' + idf-version: 'release-v5.4' - esp-idf-target: "esp32p4" - idf-version: 'v5.2.6' + idf-version: 'v5.5.2' steps: - name: Checkout repo @@ -70,9 +70,9 @@ jobs: run: git config --global --add safe.directory /__w/AtomVM/AtomVM - name: "Initialize CodeQL" - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: - languages: ${{matrix.language}} + languages: "cpp" build-mode: manual queries: +./code-queries/term-to-non-term-func.ql,./code-queries/non-term-to-term-func.ql @@ -94,7 +94,7 @@ jobs: idf.py size-components - name: "Perform CodeQL Analysis" - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 - name: Install dependencies to build host AtomVM and run qemu run: | diff --git a/.github/workflows/esp32-simtest.yaml b/.github/workflows/esp32-simtest.yaml index a09738a185..466f0f5490 100644 --- a/.github/workflows/esp32-simtest.yaml +++ b/.github/workflows/esp32-simtest.yaml @@ -96,10 +96,10 @@ jobs: idf-version: "v5.2.6" - esp-idf-target: "esp32c5" idf-version: "v5.3.4" - # CI now uses chip revision 3 that is currently only available in release-v5.5 branch + # CI now uses chip revision 3 that is currently only available in 5.5.2 include: - esp-idf-target: "esp32p4" - idf-version: "release-v5.5" + idf-version: "v5.5.2" steps: - name: Checkout repo diff --git a/CHANGELOG.md b/CHANGELOG.md index 65e7eec081..cb44a254e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,7 +73,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed `externalterm_to_term_copy` added in [0.6.5] and introduced flags to `externalterm_to_term` to perform copy. -- Release images for ESP32 chips are built with ESP-IDF v5.4 +- Release images for ESP32 chips are built with ESP-IDF v5.5 +- Only support ESP32P4 on ESP-IDF v5.5.2, v5.4.4 and later, release images are for the mass market rev3 version. - ESP32: SPI peripheral defaults to `"spi2"` instead of deprecated `hspi` - Added `zlib:compress/1` - Entry point now is `init:boot/1` if it exists. It starts the kernel application and calls `start/0` from the diff --git a/src/platforms/esp32/components/avm_builtins/gpio_driver.c b/src/platforms/esp32/components/avm_builtins/gpio_driver.c index 757965292b..3f2db2bb8d 100644 --- a/src/platforms/esp32/components/avm_builtins/gpio_driver.c +++ b/src/platforms/esp32/components/avm_builtins/gpio_driver.c @@ -723,7 +723,7 @@ static term nif_gpio_hold_dis(Context *ctx, int argc, term argv[]) return hold_dis(argv[0]); } -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 2) && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 2) && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP static term nif_gpio_deep_sleep_hold_en(Context *ctx, int argc, term argv[]) { UNUSED(ctx); @@ -785,7 +785,7 @@ static const struct Nif gpio_hold_dis_nif = .nif_ptr = nif_gpio_hold_dis }; -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 2) && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 2) && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP static const struct Nif gpio_deep_sleep_hold_en_nif = { .base.type = NIFFunctionType, .nif_ptr = nif_gpio_deep_sleep_hold_en @@ -844,7 +844,7 @@ const struct Nif *gpio_nif_get_nif(const char *nifname) return &gpio_hold_dis_nif; } -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 2) && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 2) && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP) +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP if (strcmp("gpio:deep_sleep_hold_en/0", nifname) == 0 || strcmp("Elixir.GPIO:deep_sleep_hold_en/0", nifname) == 0) { TRACE("Resolved platform nif %s ...\n", nifname); return &gpio_deep_sleep_hold_en_nif; diff --git a/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt b/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt index 9f44a694de..3710f05434 100644 --- a/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt +++ b/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt @@ -76,6 +76,7 @@ compile_erlang(test_ssl) compile_erlang(test_time_and_processes) compile_erlang(test_twdt) compile_erlang(test_tz) +compile_erlang(test_deep_sleep_hold) set(erlang_test_beams test_esp_partition.beam @@ -96,6 +97,7 @@ set(erlang_test_beams test_time_and_processes.beam test_twdt.beam test_tz.beam + test_deep_sleep_hold.beam ) if(NOT AVM_DISABLE_JIT) diff --git a/src/platforms/esp32/test/main/test_erl_sources/test_deep_sleep_hold.erl b/src/platforms/esp32/test/main/test_erl_sources/test_deep_sleep_hold.erl new file mode 100644 index 0000000000..a9d43f6850 --- /dev/null +++ b/src/platforms/esp32/test/main/test_erl_sources/test_deep_sleep_hold.erl @@ -0,0 +1,41 @@ +% +% This file is part of AtomVM. +% +% Copyright 2026 Peter M +% +% 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. +% +% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later +% + +-module(test_deep_sleep_hold). +-export([start/0]). + +start() -> + Sysinfo = erlang:system_info(esp32_chip_info), + Model = + if + is_map(Sysinfo) -> maps:get(model, Sysinfo); + true -> undefined + end, + case Model of + % esp32_p4 has no support on earlier revisions, and thus left out here. + M when M =:= esp32; M =:= esp32_s2; M =:= esp32_c3; M =:= esp32_s3; M =:= esp32_c2 -> + io:format("Testing: deep_sleep_hold_en/dis\n"), + ok = gpio:deep_sleep_hold_en(), + ok = gpio:deep_sleep_hold_dis(); + _ -> + io:format("Not testing: deep_sleep_hold_en/dis\n"), + ok + end, + ok. diff --git a/src/platforms/esp32/test/main/test_main.c b/src/platforms/esp32/test/main/test_main.c index ce6dc32bad..221a11c87d 100644 --- a/src/platforms/esp32/test/main/test_main.c +++ b/src/platforms/esp32/test/main/test_main.c @@ -515,6 +515,12 @@ TEST_CASE("test_tz", "[test_run]") TEST_ASSERT(ret_value == OK_ATOM); } +TEST_CASE("test_deep_sleep_hold", "[test_run]") +{ + term ret_value = avm_test_case("test_deep_sleep_hold.beam"); + TEST_ASSERT(ret_value == OK_ATOM); +} + #ifndef AVM_NO_SMP TEST_CASE("atomvm_smp_0", "[smp]") { @@ -613,7 +619,7 @@ TEST_CASE("test_wifi_example", "[test_run]") #endif // Works C3 on local runs, but fails GH actions -#if (ESP_IDF_VERSION_MAJOR >= 5 && !CONFIG_IDF_TARGET_ESP32C3) || (ESP_IDF_VERSION_MAJOR >= 5 && !CONFIG_ETH_USE_OPENETH) +#if (ESP_IDF_VERSION_MAJOR >= 5 && !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32P4) || (ESP_IDF_VERSION_MAJOR >= 5 && !CONFIG_IDF_TARGET_ESP32P4 && !CONFIG_ETH_USE_OPENETH) TEST_CASE("test_twdt", "[test_run]") { term ret_value = avm_test_case("test_twdt.beam"); From 06c0d2114540ba60b627d2a5a90d744b9a5356aa Mon Sep 17 00:00:00 2001 From: Peter M Date: Wed, 21 Jan 2026 20:15:25 +0100 Subject: [PATCH 2/2] ESP32-P4: built variants for revisions and wifi daughterboard Signed-off-by: Peter M --- .github/workflows/esp32-mkimage.yaml | 26 ++++++++++++++++--- CHANGELOG.md | 2 +- ... => idf_component.yml.esp32p4_wifi_remote} | 0 .../esp32/sdkconfig.defaults.esp32p4 | 8 +----- .../esp32/sdkconfig.defaults.esp32p4_c6 | 16 ++++++++++++ .../esp32/sdkconfig.defaults.esp32p4_pre | 13 ++++++++++ .../esp32/sdkconfig.defaults.esp32p4_pre_c6 | 19 ++++++++++++++ src/platforms/esp32/test/sdkconfig.ci.wokwi | 1 - 8 files changed, 73 insertions(+), 12 deletions(-) rename src/platforms/esp32/components/avm_builtins/{idf_component.yml => idf_component.yml.esp32p4_wifi_remote} (100%) create mode 100644 src/platforms/esp32/sdkconfig.defaults.esp32p4_c6 create mode 100644 src/platforms/esp32/sdkconfig.defaults.esp32p4_pre create mode 100644 src/platforms/esp32/sdkconfig.defaults.esp32p4_pre_c6 diff --git a/.github/workflows/esp32-mkimage.yaml b/.github/workflows/esp32-mkimage.yaml index e06298694a..6acf818354 100644 --- a/.github/workflows/esp32-mkimage.yaml +++ b/.github/workflows/esp32-mkimage.yaml @@ -50,7 +50,7 @@ jobs: elixir_version: ["1.17"] rebar3_version: ["3.24.0"] compiler_pkgs: ["clang-14"] - soc: ["esp32", "esp32c2", "esp32c3", "esp32s2", "esp32s3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4"] + soc: ["esp32", "esp32c2", "esp32c3", "esp32s2", "esp32s3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4", "esp32p4_pre", "esp32p4_c6", "esp32p4_pre_c6"] flavor: ["", "-elixir"] env: @@ -120,6 +120,9 @@ jobs: run: | make + - name: "Set SOC target" + run: echo "SOC_TARGET=${{ startsWith(matrix.soc, 'esp32p4') && 'esp32p4' || matrix.soc }}" >> $GITHUB_ENV + - name: "Use release defaults" if: startsWith(github.ref, 'refs/tags/') shell: bash @@ -127,6 +130,20 @@ jobs: run: | cp sdkconfig.release-defaults sdkconfig.defaults + - name: "Handle esp32p4 variants sdkconfig" + if: startsWith(matrix.soc, 'esp32p4') && matrix.soc != 'esp32p4' + shell: bash + working-directory: ./src/platforms/esp32/ + run: | + cp sdkconfig.defaults.${{ matrix.soc }} sdkconfig.defaults.esp32p4 + + - name: "Handle esp32p4 c6 variants - add wifi_remote component" + if: matrix.soc == 'esp32p4_c6' || matrix.soc == 'esp32p4_pre_c6' + shell: bash + working-directory: ./src/platforms/esp32/components/avm_builtins + run: | + cp idf_component.yml.esp32p4_wifi_remote idf_component.yml + - name: "Build ${{ matrix.soc }}${{ matrix.flavor }} with idf.py" shell: bash working-directory: ./src/platforms/esp32/ @@ -137,7 +154,7 @@ jobs: then mv partitions${{ matrix.flavor }}.csv partitions.csv fi - idf.py set-target ${{ matrix.soc }} + idf.py set-target ${{ env.SOC_TARGET }} idf.py reconfigure idf.py build @@ -147,11 +164,14 @@ jobs: if [ -z "${{ matrix.flavor }}" ] then ./mkimage.sh + if [ "${{ matrix.soc }}" != "${{ env.SOC_TARGET }}" ]; then + mv atomvm-${{ env.SOC_TARGET }}.img atomvm-${{ matrix.soc }}.img + fi else FLAVOR_SUFFIX=$(echo "${{ matrix.flavor }}" | sed 's/-//g') BOOT_FILE="../../../../build/libs/esp32boot/${FLAVOR_SUFFIX}_esp32boot.avm" ./mkimage.sh --boot "$BOOT_FILE" - mv atomvm-${{ matrix.soc }}.img atomvm-${{ matrix.soc }}${{ matrix.flavor }}.img + mv atomvm-${{ env.SOC_TARGET }}.img atomvm-${{ matrix.soc }}${{ matrix.flavor }}.img fi ls -l *.img diff --git a/CHANGELOG.md b/CHANGELOG.md index cb44a254e4..94f32c9f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed `externalterm_to_term_copy` added in [0.6.5] and introduced flags to `externalterm_to_term` to perform copy. - Release images for ESP32 chips are built with ESP-IDF v5.5 -- Only support ESP32P4 on ESP-IDF v5.5.2, v5.4.4 and later, release images are for the mass market rev3 version. +- Only support ESP32P4 on ESP-IDF v5.5.2, v5.4.4 and later. - ESP32: SPI peripheral defaults to `"spi2"` instead of deprecated `hspi` - Added `zlib:compress/1` - Entry point now is `init:boot/1` if it exists. It starts the kernel application and calls `start/0` from the diff --git a/src/platforms/esp32/components/avm_builtins/idf_component.yml b/src/platforms/esp32/components/avm_builtins/idf_component.yml.esp32p4_wifi_remote similarity index 100% rename from src/platforms/esp32/components/avm_builtins/idf_component.yml rename to src/platforms/esp32/components/avm_builtins/idf_component.yml.esp32p4_wifi_remote diff --git a/src/platforms/esp32/sdkconfig.defaults.esp32p4 b/src/platforms/esp32/sdkconfig.defaults.esp32p4 index a62c2bdb5a..9726529b45 100644 --- a/src/platforms/esp32/sdkconfig.defaults.esp32p4 +++ b/src/platforms/esp32/sdkconfig.defaults.esp32p4 @@ -7,10 +7,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_SPIRAM=y -# esp-wifi-external config for ESP32-C6 esp_wifi_hosted via SDIO -# (default options for esp32-p4-function-ev-board) -CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n -CONFIG_SLAVE_IDF_TARGET_ESP32C6=y -CONFIG_LWIP_IPV6=y -CONFIG_WIFI_RMT_EXTRA_IRAM_OPT=n -CONFIG_WIFI_RMT_SLP_IRAM_OPT=n +# no external chip/wifi diff --git a/src/platforms/esp32/sdkconfig.defaults.esp32p4_c6 b/src/platforms/esp32/sdkconfig.defaults.esp32p4_c6 new file mode 100644 index 0000000000..a62c2bdb5a --- /dev/null +++ b/src/platforms/esp32/sdkconfig.defaults.esp32p4_c6 @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: AtomVM Contributors +# +# ESP32-P4 Flash and PSRAM +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y + +# esp-wifi-external config for ESP32-C6 esp_wifi_hosted via SDIO +# (default options for esp32-p4-function-ev-board) +CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n +CONFIG_SLAVE_IDF_TARGET_ESP32C6=y +CONFIG_LWIP_IPV6=y +CONFIG_WIFI_RMT_EXTRA_IRAM_OPT=n +CONFIG_WIFI_RMT_SLP_IRAM_OPT=n diff --git a/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre b/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre new file mode 100644 index 0000000000..c37bf11537 --- /dev/null +++ b/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: AtomVM Contributors +# +# ESP32-P4 Flash and PSRAM +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y + +# no esp-wifi-external + +# Support esp32p4 pre-release +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y diff --git a/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre_c6 b/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre_c6 new file mode 100644 index 0000000000..263a756fd6 --- /dev/null +++ b/src/platforms/esp32/sdkconfig.defaults.esp32p4_pre_c6 @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: AtomVM Contributors +# +# ESP32-P4 Flash and PSRAM +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y + +# esp-wifi-external config for ESP32-C6 esp_wifi_hosted via SDIO +# (default options for esp32-p4-function-ev-board) +CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n +CONFIG_SLAVE_IDF_TARGET_ESP32C6=y +CONFIG_LWIP_IPV6=y +CONFIG_WIFI_RMT_EXTRA_IRAM_OPT=n +CONFIG_WIFI_RMT_SLP_IRAM_OPT=n + +# Support esp32p4 pre-release +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y diff --git a/src/platforms/esp32/test/sdkconfig.ci.wokwi b/src/platforms/esp32/test/sdkconfig.ci.wokwi index 2d6b898873..615a0a09e9 100644 --- a/src/platforms/esp32/test/sdkconfig.ci.wokwi +++ b/src/platforms/esp32/test/sdkconfig.ci.wokwi @@ -7,4 +7,3 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y CONFIG_LWIP_IPV6=n -CONFIG_ESP32P4_SELECTS_REV_LESS_V3=n