diff --git a/.codespellrc b/.codespellrc index b79ebe6b0ad..211f5a22726 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb,components/wpa_supplicant/*,components/esp_wifi/* -ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane +ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane,assertIn write-changes = true diff --git a/.gitlab/ci/default-build-test-rules.yml b/.gitlab/ci/default-build-test-rules.yml index b0ea742f6a2..2fbd2205212 100644 --- a/.gitlab/ci/default-build-test-rules.yml +++ b/.gitlab/ci/default-build-test-rules.yml @@ -11,7 +11,6 @@ extra_default_build_targets: - esp32c5 bypass_check_test_targets: - - esp32c5 - esp32c61 # # These lines would diff --git a/Kconfig b/Kconfig index d7240e63290..b5c529cbebb 100644 --- a/Kconfig +++ b/Kconfig @@ -122,7 +122,6 @@ mainmenu "Espressif IoT Development Framework Configuration" default "y" if IDF_TARGET="esp32c5" select FREERTOS_UNICORE select IDF_TARGET_ARCH_RISCV - select IDF_ENV_FPGA config IDF_TARGET_ESP32P4 bool diff --git a/components/app_update/test_apps/.build-test-rules.yml b/components/app_update/test_apps/.build-test-rules.yml index 82bea1b0fc6..d5682ad14d0 100644 --- a/components/app_update/test_apps/.build-test-rules.yml +++ b/components/app_update/test_apps/.build-test-rules.yml @@ -4,4 +4,4 @@ components/app_update/test_apps: disable: - if: IDF_TARGET in ["esp32c5"] temporary: true - reason: target esp32c5 is not supported yet # TODO: [ESP32C5] IDF-8638 + reason: target esp32c5 is not supported yet # TODO: [ESP32C5] IDF-8640, IDF-10317 diff --git a/components/app_update/test_apps/pytest_app_update_ut.py b/components/app_update/test_apps/pytest_app_update_ut.py index 2d28f87622d..bd5902cb4f5 100644 --- a/components/app_update/test_apps/pytest_app_update_ut.py +++ b/components/app_update/test_apps/pytest_app_update_ut.py @@ -19,6 +19,7 @@ def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None: @pytest.mark.supported_targets +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic def test_app_update(dut: Dut) -> None: extra_data = dut.parse_test_menu() diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index c318399d963..4ac03c56cd1 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -248,6 +248,8 @@ menu "Bootloader config" Protects the unmapped memory regions of the entire address space from unintended accesses. This will ensure that an exception will be triggered whenever the CPU performs a memory operation on unmapped regions of the address space. + NOTE: Disabling this config on some targets (ESP32-C6, ESP32-H2, ESP32-C5) would not generate + an exception when reading from or writing to 0x0. config BOOTLOADER_WDT_ENABLE bool "Use RTC watchdog in start code" diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c index d1cf55eddf8..3f04c45b7c7 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c @@ -28,7 +28,6 @@ #include "hal/mmu_ll.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" -#include "hal/clk_tree_ll.h" void bootloader_flash_update_id() { @@ -204,11 +203,6 @@ static void bootloader_spi_flash_resume(void) esp_err_t bootloader_init_spi_flash(void) { - // On ESP32C5, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration - // Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at - // 80MHz after the switch. PLL = 480MHz, so divider is 6. - clk_ll_mspi_fast_set_hs_divider(6); - bootloader_init_flash_configure(); bootloader_spi_flash_resume(); bootloader_flash_unlock(); diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index a3654ec3dd3..8099aa49553 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -53,18 +53,12 @@ __attribute__((weak)) void bootloader_clock_configure(void) clk_cfg.cpu_freq_mhz = cpu_freq_mhz; -#if CONFIG_IDF_TARGET_ESP32C5 - // TODO: [ESP32C5] IDF-9009 Check whether SOC_RTC_SLOW_CLK_SRC_RC_SLOW can be used on C5 MP - // RC150K can't do calibrate on ESP32C5MPW so not use it - clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K; -#else // Use RTC_SLOW clock source sel register field's default value, RC_SLOW, for 2nd stage bootloader // RTC_SLOW clock source will be switched according to Kconfig selection at application startup clk_cfg.slow_clk_src = rtc_clk_slow_src_get(); if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) { clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; } -#endif // Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader // RTC_FAST clock source will be switched to RC_FAST at application startup diff --git a/components/bootloader_support/src/bootloader_mem.c b/components/bootloader_support/src/bootloader_mem.c index d9f8466a1c5..4edfa82526a 100644 --- a/components/bootloader_support/src/bootloader_mem.c +++ b/components/bootloader_support/src/bootloader_mem.c @@ -47,6 +47,6 @@ void bootloader_init_mem(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE // protect memory region - esp_cpu_configure_region_protection(); // TODO: [ESP32C5] IDF-8833 PSRAM support write + esp_cpu_configure_region_protection(); #endif } diff --git a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c index 3a11e2c29e3..7009b9afae0 100644 --- a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c +++ b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c @@ -89,11 +89,7 @@ static inline void bootloader_hardware_init(void) /* Enable analog i2c master clock */ SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO); // TODO: IDF-8667 Remove this? -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); -#else // CONFIG_IDF_TARGET_ESP32C5_MP_VERSION SET_PERI_REG_MASK(MODEM_SYSCON_CLK_CONF_REG, MODEM_SYSCON_CLK_I2C_MST_SEL_160M); -#endif } static inline void bootloader_ana_reset_config(void) diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 4c0cf8615a9..4f568cea1c2 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -357,23 +357,48 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) ESP_LOGW(TAG, "Not disabled UART bootloader cache (set DIS_DOWNLOAD_ICACHE->1)"); } #endif + bool soft_dis_jtag_complete = false; +#if SOC_EFUSE_SOFT_DIS_JTAG + size_t soft_dis_jtag_cnt_val = 0; + esp_efuse_read_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, &soft_dis_jtag_cnt_val); + soft_dis_jtag_complete = (soft_dis_jtag_cnt_val == ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); + if (soft_dis_jtag_complete) { + bool hmac_key_found = false; + hmac_key_found = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG, NULL); + hmac_key_found |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL, NULL); + if (!hmac_key_found) { + ESP_LOGW(TAG, "SOFT_DIS_JTAG is set but HMAC key with respective purpose not found"); + soft_dis_jtag_complete = false; + } + } +#endif + if (!soft_dis_jtag_complete) { #if SOC_EFUSE_DIS_PAD_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)"); - } + secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)"); + } #endif #if SOC_EFUSE_DIS_USB_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)"); - } + secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)"); + } #endif +#if SOC_EFUSE_HARD_DIS_JTAG + secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)"); + } +#endif + } + #if SOC_EFUSE_DIS_DIRECT_BOOT secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); result &= secure; @@ -382,14 +407,6 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) } #endif -#if SOC_EFUSE_HARD_DIS_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)"); - } -#endif - #if SOC_EFUSE_DIS_BOOT_REMAP secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_BOOT_REMAP); result &= secure; diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 9015bdfd5ab..9df2e6278c3 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -298,38 +298,47 @@ bool esp_secure_boot_cfg_verify_release_mode(void) } #endif -#if SOC_EFUSE_HARD_DIS_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)"); - } -#endif - + bool soft_dis_jtag_complete = false; #if SOC_EFUSE_SOFT_DIS_JTAG size_t soft_dis_jtag_cnt_val = 0; esp_efuse_read_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, &soft_dis_jtag_cnt_val); - if (soft_dis_jtag_cnt_val != ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count) { - result &= secure; - ESP_LOGW(TAG, "Not disabled JTAG in the soft way (set SOFT_DIS_JTAG->max)"); + soft_dis_jtag_complete = (soft_dis_jtag_cnt_val == ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); + if (soft_dis_jtag_complete) { + bool hmac_key_found = false; + hmac_key_found = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG, NULL); + hmac_key_found |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL, NULL); + if (!hmac_key_found) { + ESP_LOGW(TAG, "SOFT_DIS_JTAG is set but HMAC key with respective purpose not found"); + soft_dis_jtag_complete = false; + } } #endif + if (!soft_dis_jtag_complete) { +#if SOC_EFUSE_HARD_DIS_JTAG + secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)"); + } +#endif + #if SOC_EFUSE_DIS_PAD_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)"); - } + secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)"); + } #endif #if SOC_EFUSE_DIS_USB_JTAG - secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); - result &= secure; - if (!secure) { - ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)"); - } + secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); + result &= secure; + if (!secure) { + ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)"); + } #endif + } #ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE secure = esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); diff --git a/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py b/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py index 7016cd6b94a..6dbf4030a30 100644 --- a/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py +++ b/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.generic @pytest.mark.esp32 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32s2 diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index 3996803d35b..5f428f91411 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit 3996803d35bcb79283bb7dcff60a11092339a838 +Subproject commit 5f428f914114c88470bf0a785f08840c2b35abca diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index c2b9d7c8c2a..ed6c0b4e0ab 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit c2b9d7c8c2ab4872ffe4f0501c4753fcbc96ba48 +Subproject commit ed6c0b4e0ab3b8ddce5d8bc65e417b1adcbca5b4 diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index c2c9f4161f2..2d69367e13a 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit c2c9f4161f2ed200dbbcec71fbfd26da0241f376 +Subproject commit 2d69367e13a928afb73d1a8c579c0dad98eb9393 diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 605b831211c..4fa8a1090b8 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -217,6 +217,7 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) evbuf = ble_transport_alloc_evt(1); /* Skip advertising report if we're out of memory */ if (!evbuf) { + ESP_LOGI(TAG, "Skipping advertising report due to low memory"); return 0; } } else { diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 73112f9b406..74f81e10d89 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 73112f9b4068ef7dc541c88c555ff829bebb9f8f +Subproject commit 74f81e10d8911e6206dfd75a2459dbebe5886d10 diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index b4e8409af90..e585ab7e89c 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -1091,9 +1091,9 @@ int linenoiseProbe(void) { if (cb < 0) { continue; } - if (read_bytes == 0 && c != '\x1b') { - /* invalid response */ - break; + if (read_bytes == 0 && c != ESC) { + /* invalid response, try again until the timeout triggers */ + continue; } read_bytes += cb; } diff --git a/components/console/test_apps/console/sdkconfig.ci.defaults.linux b/components/console/test_apps/console/sdkconfig.ci.defaults.linux index 640c6739d09..9b39f10b99e 100644 --- a/components/console/test_apps/console/sdkconfig.ci.defaults.linux +++ b/components/console/test_apps/console/sdkconfig.ci.defaults.linux @@ -1,4 +1 @@ CONFIG_IDF_TARGET="linux" - -# Not necessary on Linux -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=n diff --git a/components/console/test_apps/console/sdkconfig.ci.sorted.linux b/components/console/test_apps/console/sdkconfig.ci.sorted.linux index aa7094abbb6..c672cea1ca3 100644 --- a/components/console/test_apps/console/sdkconfig.ci.sorted.linux +++ b/components/console/test_apps/console/sdkconfig.ci.sorted.linux @@ -1,7 +1,4 @@ CONFIG_IDF_TARGET="linux" -# Not necessary on Linux -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=n - # enable sorted commands in the help command CONFIG_CONSOLE_SORTED_HELP=y diff --git a/components/console/test_apps/console/sdkconfig.defaults.linux b/components/console/test_apps/console/sdkconfig.defaults.linux deleted file mode 100644 index e1ed9340db8..00000000000 --- a/components/console/test_apps/console/sdkconfig.defaults.linux +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=n diff --git a/components/driver/deprecated/driver/rmt.h b/components/driver/deprecated/driver/rmt.h index c99bde31bed..e162b147aa8 100644 --- a/components/driver/deprecated/driver/rmt.h +++ b/components/driver/deprecated/driver/rmt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -152,10 +152,10 @@ esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t hi esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en); /** -* @brief Get RMT memory low power mode. +* @brief Check if the RMT memory is force powered down * -* @param channel RMT channel -* @param pd_en Pointer to accept RMT memory low power mode. +* @param channel RMT channel (actually this function is configured for all channels) +* @param pd_en Pointer to accept the result * * @return * - ESP_ERR_INVALID_ARG Parameter error diff --git a/components/driver/deprecated/rmt_legacy.c b/components/driver/deprecated/rmt_legacy.c index 67e8133df2b..65a9cdaeec8 100644 --- a/components/driver/deprecated/rmt_legacy.c +++ b/components/driver/deprecated/rmt_legacy.c @@ -252,7 +252,11 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en) { ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); RMT_ENTER_CRITICAL(); - rmt_ll_power_down_mem(rmt_contex.hal.regs, pd_en); + if (pd_en) { + rmt_ll_mem_force_power_off(rmt_contex.hal.regs); + } else { + rmt_ll_mem_power_by_pmu(rmt_contex.hal.regs); + } RMT_EXIT_CRITICAL(); return ESP_OK; } @@ -261,7 +265,7 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en) { ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); RMT_ENTER_CRITICAL(); - *pd_en = rmt_ll_is_mem_powered_down(rmt_contex.hal.regs); + *pd_en = rmt_ll_is_mem_force_powered_down(rmt_contex.hal.regs); RMT_EXIT_CRITICAL(); return ESP_OK; } diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index bb61cea137c..4acec4d44cf 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -32,7 +32,7 @@ components/driver/test_apps/legacy_i2c_driver: disable: - if: IDF_TARGET == "esp32c5" temporary: true - reason: not support yet # TODO: [ESP32C5] IDF-8694 + reason: not support yet # TODO: [ESP32C5] IDF-10307 disable_test: - if: IDF_TARGET == "esp32p4" temporary: true @@ -54,12 +54,20 @@ components/driver/test_apps/legacy_mcpwm_driver: components/driver/test_apps/legacy_pcnt_driver: disable: - if: SOC_PCNT_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO [ESP32C5] IDF-10341 depends_filepatterns: - components/driver/deprecated/**/*pcnt* components/driver/test_apps/legacy_rmt_driver: disable: - if: SOC_RMT_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO: [ESP32C5] IDF-10330 depends_filepatterns: - components/driver/deprecated/**/*rmt* diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py index e7ae5f6d371..a5a9a9a1fff 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py @@ -7,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32s3 @pytest.mark.esp32c6 @pytest.mark.esp32h2 diff --git a/components/driver/test_apps/legacy_i2c_driver/pytest_i2c_legacy.py b/components/driver/test_apps/legacy_i2c_driver/pytest_i2c_legacy.py index d32f69c6b1a..841bb08618c 100644 --- a/components/driver/test_apps/legacy_i2c_driver/pytest_i2c_legacy.py +++ b/components/driver/test_apps/legacy_i2c_driver/pytest_i2c_legacy.py @@ -5,7 +5,7 @@ @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8960 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='esp32p4 support TBD, C5 failed') # TODO: IDF-8960, [ESP32C5] IDF-10307 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py b/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py index 08cf31d5ab4..a8a9e25bd1f 100644 --- a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py +++ b/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py b/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py index 355ddb908bc..68f8593a260 100644 --- a/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py +++ b/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +# @pytest.mark.esp32c5 # TODO [ESP32C5] IDF-10341 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py b/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py index a49ce250f8c..104beefc137 100644 --- a/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py +++ b/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -9,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10330 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_coex/esp32h2/esp_coex_adapter.c b/components/esp_coex/esp32h2/esp_coex_adapter.c index 6cdfdd9bd99..936f8f2ce84 100644 --- a/components/esp_coex/esp32h2/esp_coex_adapter.c +++ b/components/esp_coex/esp32h2/esp_coex_adapter.c @@ -21,7 +21,7 @@ #include "soc/rtc.h" #include "esp_private/esp_clk.h" #include "private/esp_coexist_adapter.h" -#include "esp32c6/rom/ets_sys.h" +#include "esp32h2/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/lib b/components/esp_coex/lib index 2363239dded..56d324c3fe3 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit 2363239ddeda69523a4ed79e55815be21115200f +Subproject commit 56d324c3fe3fb7649f8736bbb3b9f00b7f612449 diff --git a/components/esp_driver_gpio/test_apps/.build-test-rules.yml b/components/esp_driver_gpio/test_apps/.build-test-rules.yml index f0eb84e6e24..9394fb7da16 100644 --- a/components/esp_driver_gpio/test_apps/.build-test-rules.yml +++ b/components/esp_driver_gpio/test_apps/.build-test-rules.yml @@ -2,9 +2,9 @@ components/esp_driver_gpio/test_apps: disable_test: - - if: IDF_TARGET == "esp32p4" + - if: IDF_TARGET in ["esp32p4", "esp32c5"] temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8968 + reason: test not pass, should be re-enable # TODO: [ESP32P4] IDF-8968 [ESP32C5] IDF-10331 depends_components: - esp_driver_gpio diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c index 44d93165a9d..fa6af224627 100644 --- a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c @@ -238,7 +238,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") #if SOC_DEEP_SLEEP_SUPPORTED // It is not necessary to test every rtcio pin, it will take too much ci testing time for deep sleep // Only tests on s_test_map[TEST_RTCIO_DEEP_SLEEP_PIN_INDEX] pin -// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5, H2: IO12) these pads' default configuration is low level +// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5, H2: IO12, P4: IO5, C5: IO5) these pads' default configuration is low level #define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 static void rtcio_deep_sleep_hold_test_first_stage(void) diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h index e2eb1f00d34..a33d64f0fbd 100644 --- a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h @@ -93,7 +93,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_20, //GPIO20 GPIO_NUM_21, //GPIO21 }; -#elif CONFIG_IDF_TARGET_ESP32C6 +#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5 // Has no input-only rtcio pins, all pins support pull-up/down #define RTCIO_SUPPORT_PU_PD(num) 1 #define TEST_GPIO_PIN_COUNT 8 diff --git a/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py index 2af5378174c..446d23dddc6 100644 --- a/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py +++ b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded_idf import IdfDut @@ -10,7 +9,8 @@ ] -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') +# TODO: [ESP32C5] IDF-10331 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='esp32p4 support TBD, c5 test failed') @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) diff --git a/components/esp_driver_i2c/i2c_common.c b/components/esp_driver_i2c/i2c_common.c index 8c3f86952e0..19af0a2977a 100644 --- a/components/esp_driver_i2c/i2c_common.c +++ b/components/esp_driver_i2c/i2c_common.c @@ -127,7 +127,7 @@ static esp_err_t s_i2c_bus_handle_acquire(i2c_port_num_t port_num, i2c_bus_handl return ret; } -static bool i2c_bus_occupied(i2c_port_num_t port_num) +bool i2c_bus_occupied(i2c_port_num_t port_num) { return s_i2c_platform.buses[port_num] != NULL; } diff --git a/components/esp_driver_i2c/i2c_master.c b/components/esp_driver_i2c/i2c_master.c index 66d2454a0df..68fdd60cbed 100644 --- a/components/esp_driver_i2c/i2c_master.c +++ b/components/esp_driver_i2c/i2c_master.c @@ -46,6 +46,15 @@ static const char *TAG = "i2c.master"; #define I2C_FIFO_LEN(port_num) (SOC_I2C_FIFO_LEN) #endif +// Use the platform to same master bus handle +typedef struct i2c_master_bus_platform_t i2c_master_bus_platform_t; + +struct i2c_master_bus_platform_t { + i2c_master_bus_handle_t handle[SOC_I2C_NUM]; +}; + +static i2c_master_bus_platform_t s_platform; + static esp_err_t s_i2c_master_clear_bus(i2c_bus_handle_t handle) { #if !SOC_I2C_SUPPORT_HW_CLR_BUS @@ -989,6 +998,7 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast xSemaphoreGive(i2c_master->cmd_semphr); *ret_bus_handle = i2c_master; + s_platform.handle[i2c_port_num] = i2c_master; return ESP_OK; err: @@ -1075,6 +1085,18 @@ esp_err_t i2c_master_bus_reset(i2c_master_bus_handle_t bus_handle) return ESP_OK; } +esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle) +{ + ESP_RETURN_ON_FALSE((port_num < SOC_I2C_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number"); + if (i2c_bus_occupied(port_num) == false) { + ESP_LOGE(TAG, "this port has not been initialized, please initialize it first"); + return ESP_ERR_INVALID_STATE; + } else { + *ret_handle = s_platform.handle[port_num]; + } + return ESP_OK; +} + esp_err_t i2c_master_multi_buffer_transmit(i2c_master_dev_handle_t i2c_dev, i2c_master_transmit_multi_buffer_info_t *buffer_info_array, size_t array_size, int xfer_timeout_ms) { ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized"); diff --git a/components/esp_driver_i2c/i2c_private.h b/components/esp_driver_i2c/i2c_private.h index ae33a26ea6a..a78dfdd0674 100644 --- a/components/esp_driver_i2c/i2c_private.h +++ b/components/esp_driver_i2c/i2c_private.h @@ -252,6 +252,14 @@ esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, soc_module_clk_t clk_ */ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle); +/** + * @brief Check whether bus is acquired + * + * @param port_num number of port + * @return true if the bus is occupied, false if the bus is not occupied. +*/ +bool i2c_bus_occupied(i2c_port_num_t port_num); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_i2c/include/esp_private/i2c_platform.h b/components/esp_driver_i2c/include/esp_private/i2c_platform.h new file mode 100644 index 00000000000..f18cf53c99c --- /dev/null +++ b/components/esp_driver_i2c/include/esp_private/i2c_platform.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "driver/i2c_types.h" +#include "hal/gpio_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Retrieves the I2C master bus handle for a specified I2C port number. + * + * This function retrieves the I2C master bus handle for the + * given I2C port number. Please make sure the handle has already been initialized, and this + * function would simply returns the existing handle. Note that the returned handle still can't be used concurrently + * + * @param port_num I2C port number for which the handle is to be retrieved. + * @param ret_handle Pointer to a variable where the retrieved handle will be stored. + * @return + * - ESP_OK: Success. The handle is retrieved successfully. + * - ESP_ERR_INVALID_ARG: Invalid argument, such as invalid port number + * - ESP_ERR_INVALID_STATE: Invalid state, such as the I2C port is not initialized. + */ +esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_i2c/test_apps/.build-test-rules.yml b/components/esp_driver_i2c/test_apps/.build-test-rules.yml index 19b812ef61f..45214c12ad0 100644 --- a/components/esp_driver_i2c/test_apps/.build-test-rules.yml +++ b/components/esp_driver_i2c/test_apps/.build-test-rules.yml @@ -4,9 +4,9 @@ components/esp_driver_i2c/test_apps/i2c_test_apps: disable: - if: SOC_I2C_SUPPORTED != 1 disable_test: - - if: IDF_TARGET == "esp32p4" + - if: IDF_TARGET in ["esp32p4", "esp32c5"] temporary: true - reason: lack of runners + reason: lack of runners, c5 test failed # TODO: [ESP32P4] IDF-8960, [ESP32C5] IDF-10332 depends_components: - esp_driver_i2c # Following dependency is needed because they might increase lazy installed memory diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c index 45ec47b06b0..91296a6eedd 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c @@ -19,6 +19,7 @@ #include "esp_private/periph_ctrl.h" #include "driver/gpio.h" #include "driver/i2c_master.h" +#include "esp_private/i2c_platform.h" #include "esp_rom_gpio.h" #include "esp_log.h" #include "test_utils.h" @@ -345,3 +346,19 @@ TEST_CASE("I2C master transaction receive check nack return value", "[i2c]") TEST_ESP_ERR(ESP_ERR_INVALID_STATE, i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); _test_i2c_del_bus_device(bus_handle, dev_handle); } + +TEST_CASE("Test get handle with known port", "[i2c]") +{ + i2c_master_bus_handle_t handle; + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, i2c_master_get_bus_handle(10, &handle)); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, i2c_master_get_bus_handle(0, &handle)); + + i2c_master_bus_handle_t bus_handle; + i2c_master_dev_handle_t dev_handle; + _test_i2c_new_bus_device(&bus_handle, &dev_handle); + TEST_ESP_OK(i2c_master_get_bus_handle(0, &handle)); + + // Check the handle retrieved is as same as original handle + TEST_ASSERT((uint32_t)bus_handle == (uint32_t)handle); + _test_i2c_del_bus_device(bus_handle, dev_handle); +} diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py index 95ce5a8ed14..6365b4ca17d 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py @@ -6,7 +6,8 @@ @pytest.mark.supported_targets @pytest.mark.generic -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8960 +# TODO: [ESP32P4] IDF-8960, [ESP32C5] IDF-10332 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='esp32p4 support TBD, c5 test failed') @pytest.mark.parametrize( 'config', [ diff --git a/components/esp_driver_i2s/test_apps/.build-test-rules.yml b/components/esp_driver_i2s/test_apps/.build-test-rules.yml index fa1041bd866..cf1abd358c2 100644 --- a/components/esp_driver_i2s/test_apps/.build-test-rules.yml +++ b/components/esp_driver_i2s/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/esp_driver_i2s/test_apps/i2s: disable: - if: SOC_I2S_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO [ESP32C5] IDF-10343 depends_components: - esp_driver_i2s - esp_driver_pcnt @@ -12,7 +16,7 @@ components/esp_driver_i2s/test_apps/i2s_multi_dev: - if: SOC_I2S_SUPPORTED != 1 - if: SOC_I2S_HW_VERSION_2 != 1 disable_test: - - if: IDF_TARGET == "esp32p4" + - if: IDF_TARGET in ["esp32p4", "esp32c5"] # TODO: [ESP32C5] IDF- 10321 temporary: true reason: lack of runners depends_components: diff --git a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py index 44017eb6924..eeb7eefaaf9 100644 --- a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py +++ b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py @@ -7,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32c3 +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10343 @pytest.mark.esp32c6 @pytest.mark.esp32s3 @pytest.mark.esp32h2 diff --git a/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py b/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py index 81fe933e11f..3d53063d50e 100644 --- a/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py +++ b/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py @@ -5,6 +5,7 @@ @pytest.mark.esp32s3 @pytest.mark.esp32c3 +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF- 10321 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.generic_multi_device diff --git a/components/esp_driver_ledc/test_apps/.build-test-rules.yml b/components/esp_driver_ledc/test_apps/.build-test-rules.yml index 00d99826d13..9fe6d7d7f30 100644 --- a/components/esp_driver_ledc/test_apps/.build-test-rules.yml +++ b/components/esp_driver_ledc/test_apps/.build-test-rules.yml @@ -4,8 +4,8 @@ components/esp_driver_ledc/test_apps/ledc: disable: - if: SOC_LEDC_SUPPORTED != 1 disable_test: - - if: IDF_TARGET == "esp32p4" + - if: IDF_TARGET in ["esp32p4", "esp32c5"] temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8969 + reason: test not pass, should be re-enable # TODO: [ESP32P4] IDF-8969, [ESP32C5] IDF-10333 depends_components: - esp_driver_ledc diff --git a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py index c93955b3a94..995b5793db0 100644 --- a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py +++ b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py @@ -1,12 +1,13 @@ -# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded_idf import IdfDut @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='skip due to duplication with test_ledc_psram, p4 TBD') # TODO: IDF-8969 +# TODO: [ESP32P4] IDF-8969, [ESP32C5] IDF-10333 +@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4', 'esp32c5'], + reason='skip due to duplication with test_ledc_psram, p4 TBD, c5 test failed') @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_driver_mcpwm/test_apps/.build-test-rules.yml b/components/esp_driver_mcpwm/test_apps/.build-test-rules.yml index cbc941233cd..14c7a062828 100644 --- a/components/esp_driver_mcpwm/test_apps/.build-test-rules.yml +++ b/components/esp_driver_mcpwm/test_apps/.build-test-rules.yml @@ -3,5 +3,9 @@ components/esp_driver_mcpwm/test_apps/mcpwm: disable: - if: SOC_MCPWM_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: test not pass, should be re-enable # TODO: [ESP32C5] IDF-10334 depends_components: - esp_driver_mcpwm diff --git a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py index bbbdf701967..aab249be52c 100644 --- a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py +++ b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.esp32s3 +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10334 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py index a6a6d8ec4e1..3db44388b6c 100644 --- a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py +++ b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py @@ -4,6 +4,7 @@ from pytest_embedded import Dut +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_driver_pcnt/include/driver/pulse_cnt.h b/components/esp_driver_pcnt/include/driver/pulse_cnt.h index f1a66c6c3d4..24123b11ff2 100644 --- a/components/esp_driver_pcnt/include/driver/pulse_cnt.h +++ b/components/esp_driver_pcnt/include/driver/pulse_cnt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -52,7 +52,7 @@ typedef bool (*pcnt_watch_cb_t)(pcnt_unit_handle_t unit, const pcnt_watch_event_ * @note When CONFIG_PCNT_ISR_IRAM_SAFE is enabled, the callback itself and functions callbed by it should be placed in IRAM. */ typedef struct { - pcnt_watch_cb_t on_reach; /*!< Called when PCNT unit counter reaches any watch point */ + pcnt_watch_cb_t on_reach; /*!< Called when PCNT unit counter reaches any watch point or step notify*/ } pcnt_event_callbacks_t; /** @@ -65,6 +65,10 @@ typedef struct { if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ struct { uint32_t accum_count: 1; /*!< Whether to accumulate the count value when overflows at the high/low limit */ +#if SOC_PCNT_SUPPORT_STEP_NOTIFY + uint32_t en_step_notify_up: 1; /*!< Enable step notify in the positive direction*/ + uint32_t en_step_notify_down: 1; /*!< Enable step notify in the negative direction*/ +#endif } flags; /*!< Extra flags */ } pcnt_unit_config_t; @@ -283,7 +287,6 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt /** * @brief Add a watch point for PCNT unit, PCNT will generate an event when the counter value reaches the watch point value * - * * @param[in] unit PCNT unit handle created by `pcnt_new_unit()` * @param[in] watch_point Value to be watched * @return @@ -308,6 +311,31 @@ esp_err_t pcnt_unit_add_watch_point(pcnt_unit_handle_t unit, int watch_point); */ esp_err_t pcnt_unit_remove_watch_point(pcnt_unit_handle_t unit, int watch_point); +/** + * @brief Add a step notify for PCNT unit, PCNT will generate an event when the incremental(can be positive or negative) of counter value reaches the step interval + * + * @param[in] unit PCNT unit handle created by `pcnt_new_unit()` + * @param[in] step_interval PCNT step notify interval value + * @return + * - ESP_OK: Add step notify successfully + * - ESP_ERR_INVALID_ARG: Add step notify failed because of invalid argument (e.g. the value incremental to be watched is out of the limitation set in `pcnt_unit_config_t`) + * - ESP_ERR_INVALID_STATE: Add step notify failed because the step notify has already been added + * - ESP_FAIL: Add step notify failed because of other error + */ +esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval); + +/** + * @brief Remove a step notify for PCNT unit + * + * @param[in] unit PCNT unit handle created by `pcnt_new_unit()` + * @return + * - ESP_OK: Remove step notify successfully + * - ESP_ERR_INVALID_ARG: Remove step notify failed because of invalid argument + * - ESP_ERR_INVALID_STATE: Remove step notify failed because the step notify was not added by `pcnt_unit_add_watch_step()` yet + * - ESP_FAIL: Remove step notify failed because of other error + */ +esp_err_t pcnt_unit_remove_watch_step(pcnt_unit_handle_t unit); + /** * @brief Create PCNT channel for specific unit, each PCNT has several channels associated with it * diff --git a/components/esp_driver_pcnt/src/pulse_cnt.c b/components/esp_driver_pcnt/src/pulse_cnt.c index ce9619de23a..e25dafc00bf 100644 --- a/components/esp_driver_pcnt/src/pulse_cnt.c +++ b/components/esp_driver_pcnt/src/pulse_cnt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -93,8 +93,10 @@ struct pcnt_unit_t { int unit_id; // allocated unit numerical ID int low_limit; // low limit value int high_limit; // high limit value - int clear_signal_gpio_num; // which gpio clear signal input + int step_limit; // step limit value + int clear_signal_gpio_num; // which gpio clear signal input int accum_value; // accumulated count value + int step_interval; // PCNT step notify interval value pcnt_chan_t *channels[SOC_PCNT_CHANNELS_PER_UNIT]; // array of PCNT channels pcnt_watch_point_t watchers[PCNT_LL_WATCH_EVENT_MAX]; // array of PCNT watchers intr_handle_t intr; // interrupt handle @@ -107,6 +109,10 @@ struct pcnt_unit_t { void *user_data; // user data registered by user, which would be passed to the right callback function struct { uint32_t accum_count: 1; /*!< Whether to accumulate the count value when overflows at the high/low limit */ +#if SOC_PCNT_SUPPORT_STEP_NOTIFY + uint32_t en_step_notify_up: 1; /*!< Enable step notify in the positive direction*/ + uint32_t en_step_notify_down: 1; /*!< Enable step notify in the negative direction*/ +#endif } flags; }; @@ -194,7 +200,9 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & PCNT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err, TAG, "invalid interrupt priority:%d", config->intr_priority); } - +#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT + ESP_GOTO_ON_FALSE(!(config->flags.en_step_notify_up && config->flags.en_step_notify_down), ESP_ERR_NOT_SUPPORTED, err, TAG, "This target can only notify in one direction"); +#endif unit = heap_caps_calloc(1, sizeof(pcnt_unit_t), PCNT_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no mem for unit"); // register unit to the group (because one group can have several units) @@ -244,6 +252,19 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re unit->clear_signal_gpio_num = -1; unit->flags.accum_count = config->flags.accum_count; +#if SOC_PCNT_SUPPORT_STEP_NOTIFY + unit->flags.en_step_notify_down = config->flags.en_step_notify_down; + unit->flags.en_step_notify_up = config->flags.en_step_notify_up; +#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT + if (config->flags.en_step_notify_up) { + unit->step_limit = config->high_limit; + } else if (config->flags.en_step_notify_down) { + unit->step_limit = config->low_limit; + } + pcnt_ll_set_step_limit_value(group->hal.dev, unit_id, unit->step_limit); +#endif +#endif + // clear/pause register is shared by all units, so using group's spinlock portENTER_CRITICAL(&group->spinlock); pcnt_ll_stop_count(group->hal.dev, unit_id); @@ -622,6 +643,51 @@ esp_err_t pcnt_unit_remove_watch_point(pcnt_unit_handle_t unit, int watch_point) return ESP_OK; } +#if SOC_PCNT_SUPPORT_STEP_NOTIFY +esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval) +{ + pcnt_group_t *group = NULL; + + ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE((step_interval > 0 && unit->flags.en_step_notify_up) || (step_interval < 0 && unit->flags.en_step_notify_down), + ESP_ERR_INVALID_ARG, TAG, "invalid step interval"); + ESP_RETURN_ON_FALSE(unit->flags.en_step_notify_up || unit->flags.en_step_notify_down, + ESP_ERR_INVALID_STATE, TAG, "step limit is not enabled yet"); + ESP_RETURN_ON_FALSE(unit->step_interval == 0, + ESP_ERR_INVALID_STATE, TAG, "watch step has been set to %d already", unit->step_interval); + ESP_RETURN_ON_FALSE(step_interval >= unit->low_limit && step_interval <= unit->high_limit, + ESP_ERR_INVALID_ARG, TAG, "step interval out of range [%d,%d]", unit->low_limit, unit->high_limit); + ESP_RETURN_ON_FALSE(unit->step_limit % step_interval == 0, + ESP_ERR_INVALID_ARG, TAG, "step interval should be a divisor of step limit"); + + group = unit->group; + unit->step_interval = step_interval; + pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, step_interval); + // different units are mixing in the same register, so we use the group's spinlock here + portENTER_CRITICAL(&group->spinlock); + pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, true); + portEXIT_CRITICAL(&group->spinlock); + + return ESP_OK; +} + +esp_err_t pcnt_unit_remove_watch_step(pcnt_unit_handle_t unit) +{ + pcnt_group_t *group = NULL; + ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + group = unit->group; + ESP_RETURN_ON_FALSE(unit->step_interval != 0, ESP_ERR_INVALID_STATE, TAG, "watch step not added yet"); + + unit->step_interval = 0; + + portENTER_CRITICAL(&group->spinlock); + pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, false); + portEXIT_CRITICAL(&group->spinlock); + + return ESP_OK; +} +#endif //SOC_PCNT_SUPPORT_STEP_NOTIFY + esp_err_t pcnt_new_channel(pcnt_unit_handle_t unit, const pcnt_chan_config_t *config, pcnt_channel_handle_t *ret_chan) { esp_err_t ret = ESP_OK; @@ -827,27 +893,69 @@ IRAM_ATTR static void pcnt_default_isr(void *args) if (intr_status & PCNT_LL_UNIT_WATCH_EVENT(unit_id)) { pcnt_ll_clear_intr_status(group->hal.dev, PCNT_LL_UNIT_WATCH_EVENT(unit_id)); - // points watcher event + // watcher event uint32_t event_status = pcnt_ll_get_event_status(group->hal.dev, unit_id); + + // use flags to avoid multiple callbacks in one point + bool is_limit_event __attribute__((unused)) = false; + bool is_step_event = false; + // iter on each event_id while (event_status) { - int event_id = __builtin_ffs(event_status) - 1; - event_status &= (event_status - 1); // clear the right most bit - - portENTER_CRITICAL_ISR(&unit->spinlock); - if (unit->flags.accum_count) { - if (event_id == PCNT_LL_WATCH_EVENT_LOW_LIMIT) { + int watch_value = pcnt_ll_get_count(group->hal.dev, unit_id); + if (event_status & BIT(PCNT_LL_WATCH_EVENT_LOW_LIMIT)) { + event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_LOW_LIMIT)); + is_limit_event = true; + if (unit->flags.accum_count) { + portENTER_CRITICAL_ISR(&unit->spinlock); unit->accum_value += unit->low_limit; - } else if (event_id == PCNT_LL_WATCH_EVENT_HIGH_LIMIT) { + portEXIT_CRITICAL_ISR(&unit->spinlock); + } + watch_value = unit->low_limit; + } else if (event_status & BIT(PCNT_LL_WATCH_EVENT_HIGH_LIMIT)) { + event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_HIGH_LIMIT)); + is_limit_event = true; + if (unit->flags.accum_count) { + portENTER_CRITICAL_ISR(&unit->spinlock); unit->accum_value += unit->high_limit; + portEXIT_CRITICAL_ISR(&unit->spinlock); + } + watch_value = unit->high_limit; + } +#if SOC_PCNT_SUPPORT_STEP_NOTIFY + else if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT)) { + event_status &= ~(BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT)); + if (is_limit_event) { + continue; + } else if (unit->flags.accum_count) { + portENTER_CRITICAL_ISR(&unit->spinlock); + unit->accum_value += unit->step_limit; + portEXIT_CRITICAL_ISR(&unit->spinlock); + } + watch_value = unit->step_limit; + } else if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL)) { + event_status &= ~(BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL)); + is_step_event = true; + } +#endif //SOC_PCNT_SUPPORT_STEP_NOTIFY + else if (event_status & BIT(PCNT_LL_WATCH_EVENT_ZERO_CROSS)) { + event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_ZERO_CROSS)); + } else if (event_status & BIT(PCNT_LL_WATCH_EVENT_THRES0)) { + event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_THRES0)); + if (is_step_event) { + continue; + } + } else if (event_status & BIT(PCNT_LL_WATCH_EVENT_THRES1)) { + event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_THRES1)); + if (is_step_event) { + continue; } } - portEXIT_CRITICAL_ISR(&unit->spinlock); // invoked user registered callback if (on_reach) { pcnt_watch_event_data_t edata = { - .watch_point_value = unit->watchers[event_id].watch_point_value, + .watch_point_value = watch_value, .zero_cross_mode = pcnt_ll_get_zero_cross_mode(group->hal.dev, unit_id), }; if (on_reach(unit, &edata, unit->user_data)) { diff --git a/components/esp_driver_pcnt/test_apps/.build-test-rules.yml b/components/esp_driver_pcnt/test_apps/.build-test-rules.yml index d94a1f9237b..80540d51ebd 100644 --- a/components/esp_driver_pcnt/test_apps/.build-test-rules.yml +++ b/components/esp_driver_pcnt/test_apps/.build-test-rules.yml @@ -3,5 +3,9 @@ components/esp_driver_pcnt/test_apps/pulse_cnt: disable: - if: SOC_PCNT_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO [ESP32C5] IDF-10342 depends_components: - esp_driver_pcnt diff --git a/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c index 6257202c27b..e60e15db02b 100644 --- a/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -581,3 +581,114 @@ TEST_CASE("pcnt_zero_input_signal", "[pcnt]") TEST_ESP_OK(pcnt_del_unit(unit)); } #endif // SOC_PCNT_SUPPORT_CLEAR_SIGNAL + +#if SOC_PCNT_SUPPORT_STEP_NOTIFY +TEST_CASE("pcnt_step_notify_event", "[pcnt]") +{ + pcnt_unit_config_t unit_config = { + .low_limit = -100, + .high_limit = 100, + .flags.accum_count = true, + .flags.en_step_notify_down = true, + }; + + printf("install pcnt unit\r\n"); + pcnt_unit_handle_t unit = NULL; + TEST_ESP_OK(pcnt_new_unit(&unit_config, &unit)); + pcnt_glitch_filter_config_t filter_config = { + .max_glitch_ns = 1000, + }; + TEST_ESP_OK(pcnt_unit_set_glitch_filter(unit, &filter_config)); + + printf("install two pcnt channels with different edge/level action\r\n"); + pcnt_chan_config_t channel_config = { + .edge_gpio_num = TEST_PCNT_GPIO_A, + .level_gpio_num = TEST_PCNT_GPIO_B, + .flags.io_loop_back = true, + }; + pcnt_channel_handle_t channelA = NULL; + TEST_ESP_OK(pcnt_new_channel(unit, &channel_config, &channelA)); + TEST_ESP_OK(pcnt_channel_set_edge_action(channelA, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); + TEST_ESP_OK(pcnt_channel_set_level_action(channelA, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_HOLD)); + + // ensure the simulation signal in a stable state + TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_A, 1)); + TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_B, 1)); + + pcnt_event_callbacks_t cbs = { + .on_reach = test_pcnt_quadrature_reach_watch_point, + }; + test_pcnt_quadrature_context_t user_data = { + .index = 0, + .triggered_watch_values = {0}, + }; + TEST_ESP_OK(pcnt_unit_register_event_callbacks(unit, &cbs, &user_data)); + + printf("add step notify\r\n"); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 0)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 20)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, -120)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, -30)); + TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -25)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_add_watch_step(unit, -100)); + TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -100)); + TEST_ESP_OK(pcnt_unit_add_watch_point(unit, 0)); + TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -50)); +#if !SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE + // the above added watch point won't take effect at once, unless we clear the internal counter manually + TEST_ESP_OK(pcnt_unit_clear_count(unit)); +#endif + + TEST_ESP_OK(pcnt_unit_enable(unit)); + TEST_ESP_OK(pcnt_unit_start(unit)); + int count_value; + + // trigger 150 rising edge on GPIO + test_gpio_simulate_rising_edge(TEST_PCNT_GPIO_A, 150); + + printf("checking count value\r\n"); + TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value)); + printf("count_value=%d\r\n", count_value); + + for (int i = 0 ; i < user_data.index; i++) { + printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]); + } + TEST_ASSERT_EQUAL(-150, count_value); + TEST_ASSERT_EQUAL(7, user_data.index); + TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[0]); + TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[1]); + TEST_ASSERT_EQUAL(-75, user_data.triggered_watch_values[2]); + TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[3]); + TEST_ASSERT_EQUAL(-0, user_data.triggered_watch_values[4]); + TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[5]); + TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[6]); + + printf("add a new step interval\r\n"); + TEST_ESP_OK(pcnt_unit_remove_watch_step(unit)); + TEST_ESP_OK(pcnt_unit_clear_count(unit)); + TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -100)); + user_data.index = 0; + + test_gpio_simulate_rising_edge(TEST_PCNT_GPIO_A, 120); + + printf("checking count value\r\n"); + TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value)); + printf("count_value=%d\r\n", count_value); + for (int i = 0 ; i < user_data.index; i++) { + printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]); + } + + TEST_ASSERT_EQUAL(-120, count_value); + TEST_ASSERT_EQUAL(3, user_data.index); + TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[0]); + TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[1]); + TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[2]); + printf("remove step_notify and uninstall channels\r\n"); + TEST_ESP_OK(pcnt_unit_remove_watch_step(unit)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_remove_watch_step(unit)); + TEST_ESP_OK(pcnt_del_channel(channelA)); + TEST_ESP_OK(pcnt_unit_stop(unit)); + TEST_ESP_OK(pcnt_unit_disable(unit)); + TEST_ESP_OK(pcnt_del_unit(unit)); +} +#endif // SOC_PCNT_SUPPORT_STEP_NOTIFY diff --git a/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py index 5c0f4a88a5b..b2b95bcccb2 100644 --- a/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10342 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_driver_rmt/src/rmt_private.h b/components/esp_driver_rmt/src/rmt_private.h index 2cbe57e7a3c..f61082ee8ee 100644 --- a/components/esp_driver_rmt/src/rmt_private.h +++ b/components/esp_driver_rmt/src/rmt_private.h @@ -65,7 +65,7 @@ extern "C" { typedef dma_descriptor_align4_t rmt_dma_descriptor_t; #ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR -#define RMT_GET_NON_CACHE_ADDR(addr) ((addr) ? CACHE_LL_L2MEM_NON_CACHE_ADDR(addr) : 0) +#define RMT_GET_NON_CACHE_ADDR(addr) (CACHE_LL_L2MEM_NON_CACHE_ADDR(addr)) #else #define RMT_GET_NON_CACHE_ADDR(addr) (addr) #endif diff --git a/components/esp_driver_rmt/src/rmt_tx.c b/components/esp_driver_rmt/src/rmt_tx.c index 915b68d0d3e..ae61213dceb 100644 --- a/components/esp_driver_rmt/src/rmt_tx.c +++ b/components/esp_driver_rmt/src/rmt_tx.c @@ -1106,32 +1106,33 @@ static void IRAM_ATTR rmt_tx_default_isr(void *args) } #if SOC_RMT_SUPPORT_DMA -ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-dereference") // TODO IDF-10235 static bool IRAM_ATTR rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)user_data; + // tx_eof_desc_addr must be non-zero, guaranteed by the hardware rmt_dma_descriptor_t *eof_desc_nc = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(event_data->tx_eof_desc_addr); - rmt_dma_descriptor_t *n = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(eof_desc_nc->next); // next points to a cache address, needs to convert it to a non-cached one - if (n) { - rmt_dma_descriptor_t *nn = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(n->next); - // if the DMA descriptor link is still a ring (i.e. hasn't broken down by `rmt_tx_mark_eof()`), then we treat it as a valid ping-pong event - if (nn) { - // continue ping-pong transmission - rmt_tx_trans_desc_t *t = tx_chan->cur_trans; - size_t encoded_symbols = t->transmitted_symbol_num; - if (t->flags.encoding_done) { - rmt_tx_mark_eof(tx_chan); - encoded_symbols += 1; - } else { - encoded_symbols += rmt_encode_check_result(tx_chan, t); - } - t->transmitted_symbol_num = encoded_symbols; - tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2 - // tell DMA that we have a new descriptor attached - gdma_append(dma_chan); - } + if (!eof_desc_nc->next) { + return false; + } + // next points to a cache address, convert it to a non-cached one + rmt_dma_descriptor_t *n = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(eof_desc_nc->next); + if (!n->next) { + return false; } + // if the DMA descriptor link is still a ring (i.e. hasn't broken down by `rmt_tx_mark_eof()`), then we treat it as a valid ping-pong event + // continue ping-pong transmission + rmt_tx_trans_desc_t *t = tx_chan->cur_trans; + size_t encoded_symbols = t->transmitted_symbol_num; + if (t->flags.encoding_done) { + rmt_tx_mark_eof(tx_chan); + encoded_symbols += 1; + } else { + encoded_symbols += rmt_encode_check_result(tx_chan, t); + } + t->transmitted_symbol_num = encoded_symbols; + tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2 + // tell DMA that we have a new descriptor attached + gdma_append(dma_chan); return false; } -ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-dereference") #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py index d800e611ba3..cae5747513d 100644 --- a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py +++ b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 8a6092a4920..f3c7bdeaa44 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -922,6 +922,9 @@ esp_err_t spi_bus_free(spi_host_device_t host_id) if (ctx->destroy_func) { err = ctx->destroy_func(ctx->destroy_arg); + if (err != ESP_OK) { + return err; + } } spicommon_bus_free_io_cfg(&bus_attr->bus_cfg); diff --git a/components/esp_driver_spi/test_apps/.build-test-rules.yml b/components/esp_driver_spi/test_apps/.build-test-rules.yml index 1639bbf5cd2..04fab588943 100644 --- a/components/esp_driver_spi/test_apps/.build-test-rules.yml +++ b/components/esp_driver_spi/test_apps/.build-test-rules.yml @@ -12,7 +12,7 @@ components/esp_driver_spi/test_apps/master: disable_test: - if: IDF_TARGET == "esp32p4" temporary: true - reason: not supported # TODO: IDF-8942 + reason: not supported, no multi-dev runner # TODO: [ESP32P4] IDF-8942 <<: *spi_depends_default components/esp_driver_spi/test_apps/param: @@ -21,7 +21,7 @@ components/esp_driver_spi/test_apps/param: disable_test: - if: IDF_TARGET == "esp32p4" temporary: true - reason: not supported # TODO: IDF-8942 + reason: not supported, no multi-dev runner # TODO: [ESP32P4] IDF-8942 <<: *spi_depends_default components/esp_driver_spi/test_apps/slave: @@ -30,7 +30,7 @@ components/esp_driver_spi/test_apps/slave: disable_test: - if: IDF_TARGET == "esp32p4" temporary: true - reason: not supported # TODO: IDF-8942 + reason: not supported, no multi-dev runner # TODO: [ESP32P4] IDF-8942 <<: *spi_depends_default components/esp_driver_spi/test_apps/slave_hd: diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 504c448a5d6..cde48af830b 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -1757,3 +1757,30 @@ static void test_iram_slave_normal(void) TEST_CASE_MULTIPLE_DEVICES("SPI_Master:IRAM_safe", "[spi_ms]", test_master_iram, test_iram_slave_normal); #endif + +TEST_CASE("test_bus_free_safty_to_remain_devices", "[spi]") +{ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + spi_device_handle_t dev0, dev1; + spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev0)); + devcfg.spics_io_num = PIN_NUM_MISO; + TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev1)); + + int master_send; + spi_transaction_t trans_cfg = { + .tx_buffer = &master_send, + .length = sizeof(uint32_t) * 8, + }; + + TEST_ESP_OK(spi_bus_remove_device(dev0)); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, spi_bus_free(TEST_SPI_HOST)); + + //transaction should OK after a failed call to bus_free + TEST_ESP_OK(spi_device_transmit(dev1, (spi_transaction_t *)&trans_cfg)); + + TEST_ESP_OK(spi_bus_remove_device(dev1)); + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST)); +} diff --git a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py index 88e58f9b296..f791c6db634 100644 --- a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py +++ b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py @@ -28,7 +28,8 @@ def test_master_esp_flash(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942 +# TODO: [ESP32P4] IDF-8942 [ESP32C5] IDF-10322 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='no multi-dev runner') @pytest.mark.supported_targets @pytest.mark.esp32h2 @pytest.mark.generic_multi_device diff --git a/components/esp_driver_spi/test_apps/param/pytest_spi_param.py b/components/esp_driver_spi/test_apps/param/pytest_spi_param.py index fa1c3f86ad9..9c4267d63d8 100644 --- a/components/esp_driver_spi/test_apps/param/pytest_spi_param.py +++ b/components/esp_driver_spi/test_apps/param/pytest_spi_param.py @@ -16,7 +16,8 @@ def test_param_single_dev(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942 +# TODO: [ESP32P4] IDF-8942 [ESP32C5] IDF-10322 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='no multi-dev runner') @pytest.mark.supported_targets @pytest.mark.esp32h2 @pytest.mark.generic_multi_device diff --git a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py index e3637da3589..6a97d24886b 100644 --- a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py +++ b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py @@ -17,7 +17,8 @@ def test_slave_single_dev(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942 +# TODO: [ESP32P4] IDF-8942 [ESP32C5] IDF-10322 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='no multi-dev runner') @pytest.mark.supported_targets @pytest.mark.esp32h2 @pytest.mark.generic_multi_device diff --git a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py index 6bcdb80f804..1329b4912f2 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py +++ b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py @@ -8,6 +8,7 @@ @pytest.mark.esp32s3 @pytest.mark.esp32c2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.generic diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 99993989946..1cfcb6d3433 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -23,14 +23,17 @@ #include "soc/uart_periph.h" #include "driver/uart.h" #include "driver/gpio.h" -#include "driver/rtc_io.h" #include "driver/uart_select.h" -#include "driver/lp_io.h" #include "esp_private/gpio.h" #include "esp_private/uart_share_hw_ctrl.h" #include "esp_clk_tree.h" #include "sdkconfig.h" #include "esp_rom_gpio.h" +#if (SOC_UART_LP_NUM >= 1) +#include "driver/rtc_io.h" +#include "hal/rtc_io_ll.h" +#include "driver/lp_io.h" +#endif #include "clk_ctrl_os.h" #include "esp_pm.h" #include "esp_private/sleep_retention.h" @@ -744,7 +747,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r else { rtc_gpio_set_direction(tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY); rtc_gpio_init(tx_io_num); - rtc_gpio_iomux_func_sel(tx_io_num, 1); + rtc_gpio_iomux_func_sel(tx_io_num, RTCIO_LL_PIN_FUNC); lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0); } diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c index f7623139ddc..b69b82b3afa 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c @@ -19,35 +19,31 @@ #include "esp_check.h" #include "esp_private/periph_ctrl.h" +/* + Note: Before you add a workaround for an issue in this driver, please please try + to figure out the actual root cause first. The USB-serial-JTAG is a simple device, + it shouldn't need anything more than a simple, straightforward driver. +*/ + #if !SOC_RCC_IS_INDEPENDENT #define USJ_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #else #define USJ_RCC_ATOMIC() #endif -typedef enum { - FIFO_IDLE = 0, /*!< Indicates the fifo is in idle state */ - FIFO_BUSY = 1, /*!< Indicates the fifo is in busy state */ -} fifo_status_t; - -// The hardware buffer max size is 64 +// The hardware buffer max size is 64, both for RX and TX. #define USB_SER_JTAG_ENDP_SIZE (64) -#define USB_SER_JTAG_RX_MAX_SIZE (64) +#define USB_SER_JTAG_RX_MAX_SIZE (USB_SER_JTAG_ENDP_SIZE) typedef struct { intr_handle_t intr_handle; /*!< USB-SERIAL-JTAG interrupt handler */ - portMUX_TYPE spinlock; /*!< Spinlock for usb_serial_jtag */ - _Atomic fifo_status_t fifo_status; /*!< Record the status of fifo */ // RX parameters RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler */ - uint32_t rx_buf_size; /*!< TX buffer size */ - uint8_t rx_data_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash FIFO data */ // TX parameters - uint32_t tx_buf_size; /*!< TX buffer size */ RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler */ - uint8_t tx_data_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash TX FIFO data */ + uint8_t tx_stash_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash TX FIFO data */ size_t tx_stash_cnt; /*!< Number of stashed TX FIFO bytes */ } usb_serial_jtag_obj_t; @@ -55,13 +51,6 @@ static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL; static const char* USB_SERIAL_JTAG_TAG = "usb_serial_jtag"; -static size_t usb_serial_jtag_write_and_flush(const uint8_t *buf, uint32_t wr_len) -{ - size_t size = usb_serial_jtag_ll_write_txfifo(buf, wr_len); - usb_serial_jtag_ll_txfifo_flush(); - return size; -} - static void usb_serial_jtag_isr_handler_default(void *arg) { BaseType_t xTaskWoken = 0; @@ -69,77 +58,70 @@ static void usb_serial_jtag_isr_handler_default(void *arg) usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask(); if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) { + //Clear interrupt so we won't be called until the next transfer finishes. + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + // Interrupt tells us the host picked up the data we sent. // If we have more data, we can put it in the buffer and the host will pick that up next. - // Send data in isr. - // If the hardware fifo is available, write in it. Otherwise, do nothing. + // We expect the TX FIFO to be writable for this. If it's not, somehow someone else + // (ROM print routines?) have snuck in a full buffer before we got here. In that case, + // we simply ignore the interrupt, a new one will come if the buffer is empty again. if (usb_serial_jtag_ll_txfifo_writable() == 1) { - // We disable the interrupt here so that the interrupt won't be triggered if there is no data to send. - + // Retrieve data from either the stash buffer or, if that's empty, from the ring buffer. size_t queued_size; - uint8_t *queued_buff = NULL; - bool is_stashed_data = false; + uint8_t *queued_buf = NULL; if (p_usb_serial_jtag_obj->tx_stash_cnt != 0) { // Send stashed tx bytes before reading bytes from ring buffer - queued_buff = p_usb_serial_jtag_obj->tx_data_buf; + queued_buf = p_usb_serial_jtag_obj->tx_stash_buf; queued_size = p_usb_serial_jtag_obj->tx_stash_cnt; - is_stashed_data = true; } else { // Max 64 data payload size in a single EndPoint - queued_buff = (uint8_t *)xRingbufferReceiveUpToFromISR(p_usb_serial_jtag_obj->tx_ring_buf, &queued_size, USB_SER_JTAG_ENDP_SIZE); + queued_buf = (uint8_t *)xRingbufferReceiveUpToFromISR(p_usb_serial_jtag_obj->tx_ring_buf, &queued_size, USB_SER_JTAG_ENDP_SIZE); } - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); - - if (queued_buff != NULL) { - - // Although tx_queued_bytes may be larger than 0, we may have - // interrupted before xRingbufferSend() was called. - // Copy the queued buffer into the TX FIFO - - // On ringbuffer wrap-around the size can be 0 even though the buffer returned is not NULL - if (queued_size > 0) { - portENTER_CRITICAL_ISR(&p_usb_serial_jtag_obj->spinlock); - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_BUSY); - uint32_t sent_size = usb_serial_jtag_write_and_flush(queued_buff, queued_size); - portEXIT_CRITICAL_ISR(&p_usb_serial_jtag_obj->spinlock); - - if (sent_size < queued_size) { - // Not all bytes could be sent at once; stash the unwritten bytes in a tx buffer - // stash_size will not larger than USB_SER_JTAG_ENDP_SIZE because queued_size is got from xRingbufferReceiveUpToFromISR - size_t stash_size = queued_size - sent_size; - memcpy(p_usb_serial_jtag_obj->tx_data_buf, &queued_buff[sent_size], stash_size); - p_usb_serial_jtag_obj->tx_stash_cnt = stash_size; - } else { - p_usb_serial_jtag_obj->tx_stash_cnt = 0; - // assert if sent_size is larger than queued_size. - assert(sent_size <= queued_size); - } + if (queued_buf != NULL && queued_size > 0) { + // We have some data to send. Send it. + uint32_t sent_size = usb_serial_jtag_ll_write_txfifo(queued_buf, queued_size); + usb_serial_jtag_ll_txfifo_flush(); + + // Check if we were able to send everything. + if (sent_size < queued_size) { + // Not all bytes could be sent at once; stash the unwritten bytes in a buffer + // This will happen if e.g. the rom output functions manage to sneak a few bytes into the + // TX FIFO before this interrupt triggers. Note stash_size will not larger than + // USB_SER_JTAG_ENDP_SIZE because queued_size is obtained from xRingbufferReceiveUpToFromISR. + size_t stash_size = queued_size - sent_size; + memcpy(p_usb_serial_jtag_obj->tx_stash_buf, &queued_buf[sent_size], stash_size); + p_usb_serial_jtag_obj->tx_stash_cnt = stash_size; + } else { + p_usb_serial_jtag_obj->tx_stash_cnt = 0; } - if (is_stashed_data == false) { - vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buff, &xTaskWoken); + // Return the buffer if we got it from the ring buffer. + if (queued_buf != p_usb_serial_jtag_obj->tx_stash_buf) { + vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buf, &xTaskWoken); } } else { + // No data to send. // The last transmit may have sent a full EP worth of data. The host will interpret // this as a transaction that hasn't finished yet and keep the data in its internal // buffers rather than releasing it to the program listening on the CDC serial port. // We need to flush again in order to send a 0-byte packet that ends the transaction. usb_serial_jtag_ll_txfifo_flush(); - // Note that since this doesn't re-enable USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY, the - // flush will not by itself cause this ISR to be called again. + + // We will also disable the interrupt as for now there's no need to handle the + // TX interrupt again. We'll re-enable this externally if we need data sent. + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); } - } else { - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); } } if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) { - // read rx buffer(max length is 64), and send available data to ringbuffer. - // Ensure the rx buffer size is larger than RX_MAX_SIZE. + // Acknowledge interrupt usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(p_usb_serial_jtag_obj->rx_data_buf, USB_SER_JTAG_RX_MAX_SIZE); - xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, p_usb_serial_jtag_obj->rx_data_buf, rx_fifo_len, &xTaskWoken); + // Read RX FIFO and send available data to ringbuffer. + uint8_t buf[USB_SER_JTAG_RX_MAX_SIZE]; + uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(buf, USB_SER_JTAG_RX_MAX_SIZE); + xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, buf, rx_fifo_len, &xTaskWoken); } if (xTaskWoken == pdTRUE) { @@ -157,15 +139,13 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se p_usb_serial_jtag_obj = (usb_serial_jtag_obj_t*) heap_caps_calloc(1, sizeof(usb_serial_jtag_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (p_usb_serial_jtag_obj == NULL) { ESP_LOGE(USB_SERIAL_JTAG_TAG, "memory allocate error"); - err = ESP_ERR_NO_MEM; - goto _exit; + // no `goto _exit` here as there's nothing to clean up and that would make the uninstall + // routine unhappy. + return ESP_ERR_NO_MEM; } - p_usb_serial_jtag_obj->rx_buf_size = usb_serial_jtag_config->rx_buffer_size; - p_usb_serial_jtag_obj->tx_buf_size = usb_serial_jtag_config->tx_buffer_size; p_usb_serial_jtag_obj->tx_stash_cnt = 0; - p_usb_serial_jtag_obj->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; - p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(p_usb_serial_jtag_obj->rx_buf_size, RINGBUF_TYPE_BYTEBUF); + p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(usb_serial_jtag_config->rx_buffer_size, RINGBUF_TYPE_BYTEBUF); if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) { ESP_LOGE(USB_SERIAL_JTAG_TAG, "ringbuffer create error"); err = ESP_ERR_NO_MEM; @@ -183,7 +163,6 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se USJ_RCC_ATOMIC() { usb_serial_jtag_ll_enable_bus_clock(true); } - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); // Configure PHY #if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED @@ -193,10 +172,14 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se usb_serial_jtag_ll_phy_set_defaults(); // External PHY not supported. Set default values. #endif // USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | - USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | - USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + // Note: DO NOT clear the interrupt status bits here. The output routine needs + // USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY set because it needs the ISR to trigger + // as soon as data is sent; the input routine needs the status to retrieve any + // data that is still in the FIFOs. + + // We only enable the RX interrupt; we'll enable the TX one when we actually + // have anything to send. + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); err = esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, usb_serial_jtag_isr_handler_default, NULL, &p_usb_serial_jtag_obj->intr_handle); if (err != ESP_OK) { @@ -238,37 +221,29 @@ int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t ticks_t ESP_RETURN_ON_FALSE(src != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "Invalid buffer pointer."); ESP_RETURN_ON_FALSE(p_usb_serial_jtag_obj != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "The driver hasn't been initialized"); - size_t sent_data = 0; BaseType_t result = pdTRUE; - const uint8_t *buff = (const uint8_t *)src; - if (p_usb_serial_jtag_obj->fifo_status == FIFO_IDLE) { - portENTER_CRITICAL(&p_usb_serial_jtag_obj->spinlock); - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_BUSY); - sent_data = usb_serial_jtag_write_and_flush(src, size); - portEXIT_CRITICAL(&p_usb_serial_jtag_obj->spinlock); - } - - // Blocking method, Sending data to ringbuffer, and handle the data in ISR. - if (size - sent_data > 0) { - result = xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*)(buff + sent_data), size - sent_data, ticks_to_wait); - } else { - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); - } + result = xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*)src, size, ticks_to_wait); + // Re-enable the TX interrupt. If this was disabled, this will immediately trigger the ISR + // and send the things we just put in the ringbuffer. usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); return (result == pdFALSE) ? 0 : size; } +//Note that this is also called when usb_serial_jtag_driver_install errors out and as such should +//work on a half-initialized driver as well. esp_err_t usb_serial_jtag_driver_uninstall(void) { if (p_usb_serial_jtag_obj == NULL) { - ESP_LOGI(USB_SERIAL_JTAG_TAG, "ALREADY NULL"); + ESP_LOGE(USB_SERIAL_JTAG_TAG, "uninstall without install called"); return ESP_OK; } - /* Not disable the module clock and usb_pad_enable here since the USJ stdout might still depends on it. */ - //Disable tx/rx interrupt. + /* Don't disable the module clock and usb_pad_enable here since the USJ stdout might still depends on it. */ + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - esp_intr_free(p_usb_serial_jtag_obj->intr_handle); + if (p_usb_serial_jtag_obj->intr_handle) { + esp_intr_free(p_usb_serial_jtag_obj->intr_handle); + } if (p_usb_serial_jtag_obj->rx_ring_buf) { vRingbufferDelete(p_usb_serial_jtag_obj->rx_ring_buf); diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c index 9446a6d24ed..ea400bbb65d 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c @@ -121,6 +121,11 @@ static void usb_serial_jtag_tx_char(int fd, int c) do { if (usb_serial_jtag_ll_txfifo_writable()) { usb_serial_jtag_ll_write_txfifo(&cc, 1); + if (c == '\n') { + //Make sure line doesn't linger in fifo + usb_serial_jtag_ll_txfifo_flush(); + } + //update time of last successful tx to now. s_ctx.last_tx_ts = esp_timer_get_time(); break; } @@ -155,10 +160,6 @@ static ssize_t usb_serial_jtag_write(int fd, const void * data, size_t size) } } s_ctx.tx_func(fd, c); - if (c == '\n') { - //Make sure line doesn't linger in fifo - usb_serial_jtag_ll_txfifo_flush(); - } } _lock_release_recursive(&s_ctx.write_lock); return size; diff --git a/components/esp_event/test_apps/sdkconfig.defaults.linux b/components/esp_event/test_apps/sdkconfig.defaults.linux deleted file mode 100644 index e1ed9340db8..00000000000 --- a/components/esp_event/test_apps/sdkconfig.defaults.linux +++ /dev/null @@ -1 +0,0 @@ -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=n diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 45eb3932693..0807483723a 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -159,7 +159,6 @@ if(NOT BOOTLOADER_BUILD) "sleep_modem.c" # TODO: [ESP32C5] IDF-8638 "sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638 "sleep_gpio.c" # TODO: [ESP32C5] IDF-8638 - "port/esp_clk_tree_common.c" # TODO: [ESP32C5] IDF-8638 ) endif() diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 8561d769b03..6f61db54025 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -288,10 +288,7 @@ menu "Hardware Settings" # Invisible bringup bypass options for esp_hw_support component config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING bool - # TODO: [ESP32C5] IDF-8642 IDF_TARGET_ESP32C5 is added because clock - # is required when bringup on C5 beta3, remove it when clock tree is - # supported - default y if !SOC_CLK_TREE_SUPPORTED && !IDF_TARGET_ESP32C5 + default y if !SOC_CLK_TREE_SUPPORTED default n help This option is only used for new chip bringup, when diff --git a/components/esp_hw_support/esp_clk.c b/components/esp_hw_support/esp_clk.c index d777543eaca..c4a2c0c207f 100644 --- a/components/esp_hw_support/esp_clk.c +++ b/components/esp_hw_support/esp_clk.c @@ -96,7 +96,7 @@ int IRAM_ATTR esp_clk_cpu_freq(void) int IRAM_ATTR esp_clk_apb_freq(void) { // TODO: IDF-5173 Require cleanup, implementation should be unified -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C61 +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 return rtc_clk_apb_freq_get(); #else return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ); diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 0ad8003c564..aaa5f1e280a 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -19,8 +19,11 @@ entries: if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y: rtc_sleep (noflash_text) rtc_time (noflash_text) - if SOC_PMU_SUPPORTED = y: + if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y: pmu_sleep (noflash) + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: + pmu_init (noflash) + pmu_param (noflash) if SOC_USB_SERIAL_JTAG_SUPPORTED = y: sleep_console (noflash) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: diff --git a/components/esp_hw_support/port/esp32c5/CMakeLists.txt b/components/esp_hw_support/port/esp32c5/CMakeLists.txt index b7e789dd260..6a32d8aec10 100644 --- a/components/esp_hw_support/port/esp32c5/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c5/CMakeLists.txt @@ -1,10 +1,11 @@ set(srcs "rtc_clk_init.c" "rtc_time.c" "rtc_clk.c" + "pmu_init.c" + "pmu_param.c" "chip_info.c" ) - if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sar_periph_ctrl.c" "esp_crypto_lock.c") diff --git a/components/esp_hw_support/port/esp32c5/cpu_region_protect.c b/components/esp_hw_support/port/esp32c5/cpu_region_protect.c index fb9c2053f5d..e0a98735885 100644 --- a/components/esp_hw_support/port/esp32c5/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c5/cpu_region_protect.c @@ -23,6 +23,9 @@ #define CONDITIONAL_RWX RWX #endif +#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1)) + static void esp_cpu_configure_invalid_regions(void) { const unsigned PMA_NONE = PMA_L | PMA_EN; @@ -30,50 +33,50 @@ static void esp_cpu_configure_invalid_regions(void) __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; - // 1. Gap at bottom of address space - PMA_ENTRY_SET_TOR(0, SOC_DEBUG_LOW, PMA_TOR | PMA_NONE); + // 0. Gap at bottom of address space + PMA_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE); - // 2. Gap between debug region & IROM - PMA_ENTRY_SET_TOR(1, SOC_DEBUG_HIGH, PMA_NONE); + // 1. Gap between debug region & IROM + PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); + // 2. ROM has configured the ROM region to be cacheable, so we just need to lock the configuration + PMA_ENTRY_SET_TOR(3, SOC_IROM_MASK_LOW, PMA_NONE); + PMA_ENTRY_SET_TOR(4, SOC_DROM_MASK_HIGH, PMA_TOR | PMA_RX); + // 3. Gap between ROM & RAM - PMA_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + PMA_ENTRY_SET_TOR(5, SOC_DROM_MASK_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(6, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); // 4. Gap between DRAM and I_Cache - PMA_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + PMA_ENTRY_SET_TOR(7, SOC_IRAM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(8, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + + // 5. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration + // This function sets invalid regions but this is a valid memory region configuration that could have + // been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA. + PMA_ENTRY_SET_NAPOT(9, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX); - // 5. Gap between D_Cache & LP_RAM - PMA_ENTRY_SET_TOR(7, SOC_DROM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(8, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); + // 6. Gap between D_Cache & LP_RAM + PMA_ENTRY_SET_TOR(10, SOC_DROM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(11, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); - // 6. Gap between LP memory & peripheral addresses - PMA_ENTRY_SET_TOR(9, SOC_RTC_IRAM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(10, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); + // 7. Gap between LP memory & peripheral addresses + PMA_ENTRY_SET_TOR(12, SOC_RTC_IRAM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(13, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); - // 7. End of address space - PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE); + // 8. End of address space + PMA_ENTRY_SET_TOR(14, SOC_PERIPHERAL_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE); } void esp_cpu_configure_region_protection(void) { - // ROM has configured the MSPI region with RX permission, we should add W attribute for psram - PMA_ENTRY_SET_NAPOT(0, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_EN | PMA_R | PMA_W | PMA_X); - - // Configure just the area around 0x0 for now so that we at least get exceptions for - // writes/reads to NULL pointers, as well as code that relies on writes to 0x0 - // to abort/assert - PMA_ENTRY_SET_NAPOT(1, 0, SOC_DEBUG_LOW, PMA_NAPOT | PMA_EN); - - return; /* Notes on implementation: * - * 1) Note: ESP32-C6 CPU doesn't support overlapping PMP regions + * 1) Note: ESP32-C5 CPU support overlapping PMP regions // TODO: verify this statement? * - * 2) ESP32-C6 supports 16 PMA regions so we use this feature to block all the invalid address ranges + * 2) ESP32-C5 supports 16 PMA regions so we use this feature to block all the invalid address ranges * * 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range) * entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries @@ -105,10 +108,10 @@ void esp_cpu_configure_region_protection(void) * We also lock these entries so the R/W/X permissions are enforced even for machine mode */ const unsigned NONE = PMP_L; - const unsigned R = PMP_L | PMP_R; - const unsigned RW = PMP_L | PMP_R | PMP_W; - const unsigned RX = PMP_L | PMP_R | PMP_X; - const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; + __attribute__((unused)) const unsigned R = PMP_L | PMP_R; + __attribute__((unused)) const unsigned RW = PMP_L | PMP_R | PMP_W; + __attribute__((unused)) const unsigned RX = PMP_L | PMP_R | PMP_X; + __attribute__((unused)) const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; // // Configure all the invalid address regions using PMA @@ -119,36 +122,27 @@ void esp_cpu_configure_region_protection(void) // Configure all the valid address regions using PMP // - // 1. Debug region - const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_DEBUG_LOW, SOC_DEBUG_HIGH); + // 1. CPU Subsystem region - contains interrupt config registers + const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH); PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX); - _Static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region"); + _Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region"); - // 2.1 I-ROM + // 2. I/D-ROM PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX); - _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I-ROM region"); - - // 2.2 D-ROM - PMP_ENTRY_SET(3, SOC_DROM_MASK_LOW, NONE); - PMP_ENTRY_SET(4, SOC_DROM_MASK_HIGH, PMP_TOR | R); - _Static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH, "Invalid D-ROM region"); + _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); + // 3. IRAM and DRAM if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); - // 5. IRAM and DRAM - // const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH); - // PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | RWX); - // _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE); PMP_ENTRY_SET(6, SOC_IRAM_HIGH, PMP_TOR | RWX); _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); } else { #if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD extern int _iram_end; - // 5. IRAM and DRAM /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits * Bootloader might have given extra permissions and those won't be cleared */ @@ -159,55 +153,61 @@ void esp_cpu_configure_region_protection(void) PMP_ENTRY_SET(6, (int)&_iram_end, PMP_TOR | RX); PMP_ENTRY_SET(7, SOC_DRAM_HIGH, PMP_TOR | RW); #else - // 5. IRAM and DRAM - // const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH); - // PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | CONDITIONAL_RWX); - // _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); - PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE); - PMP_ENTRY_SET(6, SOC_IRAM_HIGH, PMP_TOR | RWX); + PMP_ENTRY_SET(5, SOC_IRAM_LOW, CONDITIONAL_NONE); + PMP_ENTRY_SET(6, SOC_IRAM_HIGH, PMP_TOR | CONDITIONAL_RWX); _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); #endif } - // 4. I_Cache (flash) - const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); - PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX); - _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region"); + // 4. I_Cache / D_Cache (flash) +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _instruction_reserved_end; + extern int _rodata_reserved_end; - // 5. D_Cache (flash) - const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH); - PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R); - _Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region"); + const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)); + const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)); - // 6. LP memory + PMP_ENTRY_CFG_RESET(8); + PMP_ENTRY_CFG_RESET(9); + PMP_ENTRY_CFG_RESET(10); + PMP_ENTRY_SET(8, SOC_IROM_LOW, NONE); + PMP_ENTRY_SET(9, irom_resv_end, PMP_TOR | RX); + PMP_ENTRY_SET(10, drom_resv_end, PMP_TOR | R); +#else + const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); + // Add the W attribute in the case of PSRAM + PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RWX); + _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region"); +#endif + + // 5. LP memory #if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD extern int _rtc_text_end; /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits * Bootloader might have given extra permissions and those won't be cleared */ - PMP_ENTRY_CFG_RESET(10); PMP_ENTRY_CFG_RESET(11); PMP_ENTRY_CFG_RESET(12); PMP_ENTRY_CFG_RESET(13); - PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE); + PMP_ENTRY_CFG_RESET(14); + PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); #if CONFIG_ULP_COPROC_RESERVE_MEM // First part of LP mem is reserved for coprocessor - PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); #else // CONFIG_ULP_COPROC_RESERVE_MEM // Repeat same previous entry, to ensure next entry has correct base address (TOR) - PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW, NONE); #endif // !CONFIG_ULP_COPROC_RESERVE_MEM - PMP_ENTRY_SET(12, (int)&_rtc_text_end, PMP_TOR | RX); - PMP_ENTRY_SET(13, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); + PMP_ENTRY_SET(13, (int)&_rtc_text_end, PMP_TOR | RX); + PMP_ENTRY_SET(14, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); #else - const uint32_t pmpaddr10 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); - PMP_ENTRY_SET(10, pmpaddr10, PMP_NAPOT | CONDITIONAL_RWX); + const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); + PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_RWX); _Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region"); #endif - - // 7. Peripheral addresses - const uint32_t pmpaddr14 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); - PMP_ENTRY_SET(14, pmpaddr14, PMP_NAPOT | RW); + // 6. Peripheral addresses + const uint32_t pmpaddr15 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); + PMP_ENTRY_SET(15, pmpaddr15, PMP_NAPOT | RW); _Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region"); } diff --git a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c index 77a61ea8f20..62dfe1eddda 100644 --- a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c @@ -11,21 +11,22 @@ #include "soc/rtc.h" #include "hal/clk_tree_hal.h" #include "hal/clk_tree_ll.h" -// #include "esp_private/esp_clk_tree_common.h" -#include "sdkconfig.h" +#include "esp_private/esp_clk_tree_common.h" static const char *TAG = "esp_clk_tree"; esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, uint32_t *freq_value) { - // TODO: [ESP32C5] IDF-8642 check again for MP version ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); uint32_t clk_src_freq = 0; switch (clk_src) { + case SOC_MOD_CLK_CPU: + clk_src_freq = clk_hal_cpu_get_freq_hz(); + break; case SOC_MOD_CLK_XTAL: clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; break; @@ -41,9 +42,17 @@ uint32_t *freq_value) case SOC_MOD_CLK_SPLL: clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ; break; + case SOC_MOD_CLK_RTC_SLOW: + clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RTC_FAST: + clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision); + break; case SOC_MOD_CLK_RC_FAST: - // C5-beta3 unable to calibrate to get exact RC_FAST frequency - clk_src_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL32K: + clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision); break; case SOC_MOD_CLK_XTAL_D2: clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1; diff --git a/components/esp_hw_support/port/esp32c5/include/soc/rtc.h b/components/esp_hw_support/port/esp32c5/include/soc/rtc.h index 8aeb0611736..b449d374141 100644 --- a/components/esp_hw_support/port/esp32c5/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c5/include/soc/rtc.h @@ -50,10 +50,6 @@ extern "C" { #define MHZ (1000000) -#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10) -#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12) -#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value - #define OTHER_BLOCKS_POWERUP 1 #define OTHER_BLOCKS_WAIT 1 @@ -121,21 +117,19 @@ typedef struct rtc_cpu_freq_config_s { #define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO #define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO - /** * @brief Clock source to be calibrated using rtc_clk_cal function * - * @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL - * However, this is not true on ESP32C5. The conversion to register field values is explicitly done in - * rtc_clk_cal_internal + * @note On ESP32C5, the enum values somehow reflects the register field values of PCR_32K_SEL. */ typedef enum { - RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK - // RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator - RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock - RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock - RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock - RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator + RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK + RTC_CAL_RC32K = 0, //!< Internal 32kHz RC oscillator, as one type of 32k clock + RTC_CAL_32K_XTAL = 1, //!< External 32kHz XTAL, as one type of 32k clock + RTC_CAL_32K_OSC_SLOW = 2, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock + RTC_CAL_RC_SLOW = 3, //!< Internal 150kHz RC oscillator + RTC_CAL_RC_FAST = 4, //!< Internal 20MHz RC oscillator + RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate } rtc_cal_sel_t; /** @@ -160,7 +154,7 @@ typedef struct { .xtal_freq = CONFIG_XTAL_FREQ, \ .cpu_freq_mhz = 80, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ - .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K, \ + .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ .clk_8m_clk_div = 0, \ .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ diff --git a/components/esp_hw_support/port/esp32c5/io_mux.c b/components/esp_hw_support/port/esp32c5/io_mux.c index 6e9cd843032..e8fb906555a 100644 --- a/components/esp_hw_support/port/esp32c5/io_mux.c +++ b/components/esp_hw_support/port/esp32c5/io_mux.c @@ -6,11 +6,23 @@ #include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" +#include "esp_private/periph_ctrl.h" #include "hal/gpio_ll.h" +#include "hal/rtc_io_ll.h" + +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) +#if CONFIG_ULP_COPROC_ENABLED +RTC_DATA_ATTR +#endif +static rtc_io_status_t s_rtc_io_status = { + .rtc_io_enabled_cnt = { 0 }, + .rtc_io_using_mask = 0 +}; + esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) { bool clk_conflict = false; @@ -31,3 +43,27 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_OK; } + +void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) +{ + portENTER_CRITICAL(&s_io_mux_spinlock); + if (enable) { + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); + } + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++; + } else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) { + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--; + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); + } + } + RTCIO_RCC_ATOMIC() { + if (s_rtc_io_status.rtc_io_using_mask == 0) { + rtcio_ll_enable_io_clock(false); + } else { + rtcio_ll_enable_io_clock(true); + } + } + portEXIT_CRITICAL(&s_io_mux_spinlock); +} diff --git a/components/esp_hw_support/port/esp32c5/pmu_init.c b/components/esp_hw_support/port/esp32c5/pmu_init.c index 345efa32ca3..e280fc36dc7 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_init.c +++ b/components/esp_hw_support/port/esp32c5/pmu_init.c @@ -23,13 +23,13 @@ typedef struct { const pmu_hp_system_power_param_t *power; const pmu_hp_system_clock_param_t *clock; const pmu_hp_system_digital_param_t *digital; - const pmu_hp_system_analog_param_t *analog; + pmu_hp_system_analog_param_t *analog; //param determined at runtime const pmu_hp_system_retention_param_t *retent; } pmu_hp_system_param_t; typedef struct { const pmu_lp_system_power_param_t *power; - const pmu_lp_system_analog_param_t *analog; + pmu_lp_system_analog_param_t *analog; //param determined at runtime } pmu_lp_system_param_t; pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) @@ -42,7 +42,7 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) return &pmu_context; } -void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param) { const pmu_hp_system_power_param_t *power = param->power; const pmu_hp_system_clock_param_t *clock = param->clock; @@ -101,7 +101,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); } -void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) { const pmu_lp_system_power_param_t *power = param->power; const pmu_lp_system_analog_param_t *anlg = param->analog; @@ -157,18 +157,26 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) { + assert (param->analog); + param->power = pmu_hp_system_power_param_default(mode); param->clock = pmu_hp_system_clock_param_default(mode); param->digital = pmu_hp_system_digital_param_default(mode); - param->analog = pmu_hp_system_analog_param_default(mode); + *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value param->retent = pmu_hp_system_retention_param_default(mode); + + if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + param->analog->regulator0.dbias = get_act_hp_dbias(); + } } static void pmu_hp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_hp_system_param_t param = { 0 }; for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_analog_param_t analog = {}; + pmu_hp_system_param_t param = {.analog = &analog}; + pmu_hp_system_param_default(mode, ¶m); pmu_hp_system_init(ctx, mode, ¶m); } @@ -176,15 +184,23 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx) static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) { + assert (param->analog); + param->power = pmu_lp_system_power_param_default(mode); - param->analog = pmu_lp_system_analog_param_default(mode); + *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value + + if (mode == PMU_MODE_LP_ACTIVE) { + param->analog->regulator0.dbias = get_act_lp_dbias(); + } } static void pmu_lp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_lp_system_param_t param; for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_analog_param_t analog = {}; + pmu_lp_system_param_t param = {.analog = &analog}; + pmu_lp_system_param_default(mode, ¶m); pmu_lp_system_init(ctx, mode, ¶m); } @@ -195,10 +211,6 @@ void pmu_init(void) /* Peripheral reg i2c power up */ SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); pmu_hp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance()); diff --git a/components/esp_hw_support/port/esp32c5/pmu_param.c b/components/esp_hw_support/port/esp32c5/pmu_param.c index 262bfe9fcf9..cdcc639ad50 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_param.c +++ b/components/esp_hw_support/port/esp32c5/pmu_param.c @@ -211,7 +211,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .xpd = 1, \ .slp_mem_dbias = 0, \ .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -231,7 +231,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .xpd = 1, \ .slp_mem_dbias = 0, \ .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -413,7 +413,7 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod .slp_xpd = 0, \ .xpd = 1, \ .slp_dbias = 0, \ - .dbias = LP_CALI_DBIAS \ + .dbias = LP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -447,3 +447,53 @@ const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_m assert(mode < ARRAY_SIZE(lp_analog)); return &lp_analog[mode]; } + +uint32_t get_act_hp_dbias(void) +{ + /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V + */ + uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + // uint32_t blk_version = efuse_hal_blk_version(); + // if (blk_version >= 3) { + // hp_cali_dbias = efuse_ll_get_active_hp_dbias(); + // if (hp_cali_dbias != 0) { + // //efuse dbias need to add 2 to meet the CPU frequency switching + // if (hp_cali_dbias + 2 > 31) { + // hp_cali_dbias = 31; + // } else { + // hp_cali_dbias += 2; + // } + // } else { + // hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + // ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version); + // } + // } + + return hp_cali_dbias; +} + +uint32_t get_act_lp_dbias(void) +{ + /* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V + */ + uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + // uint32_t blk_version = efuse_hal_blk_version(); + // if (blk_version >= 3) { + // lp_cali_dbias = efuse_ll_get_active_lp_dbias(); + // if (lp_cali_dbias != 0) { + // //efuse dbias need to add 2 to meet the CPU frequency switching + // if (lp_cali_dbias + 2 > 31) { + // lp_cali_dbias = 31; + // } else { + // lp_cali_dbias += 2; + // } + // } else { + // lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + // ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version); + // } + // } else { + // ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + // } + + return lp_cali_dbias; +} diff --git a/components/esp_hw_support/port/esp32c5/pmu_sleep.c b/components/esp_hw_support/port/esp32c5/pmu_sleep.c index 262ce0086e6..363b73e7cec 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c5/pmu_sleep.c @@ -168,11 +168,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default( if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS; + analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS_DEFAULT; analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS_DEFAULT; } config->analog = analog_default; @@ -280,6 +280,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp bool pmu_sleep_finish(bool dslp) { (void)dslp; + + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h b/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h deleted file mode 100644 index 524f286194c..00000000000 --- a/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize OCode - * - */ -void esp_ocode_calib_init(void); - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h index 909a5832151..7153ef4846d 100644 --- a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h @@ -19,9 +19,8 @@ extern "C" { #endif - -#define HP_CALI_DBIAS 25 -#define LP_CALI_DBIAS 26 +#define HP_CALI_DBIAS_DEFAULT 28 +#define LP_CALI_DBIAS_DEFAULT 28 // FOR XTAL FORCE PU IN SLEEP #define PMU_PD_CUR_SLEEP_ON 0 @@ -51,6 +50,9 @@ extern "C" { #define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 #define PMU_LP_DBIAS_DEEPSLEEP_0V7 23 +uint32_t get_act_hp_dbias(void); +uint32_t get_act_lp_dbias(void); + typedef struct { pmu_hp_dig_power_reg_t dig_power; pmu_hp_clk_power_reg_t clk_power; @@ -412,7 +414,7 @@ typedef struct { typedef struct pmu_sleep_machine_constant { struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t reserved0; uint16_t reserved1; @@ -424,7 +426,7 @@ typedef struct pmu_sleep_machine_constant { uint16_t power_up_wait_time_us; /* (unit: microsecond) */ } lp; struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ diff --git a/components/esp_hw_support/port/esp32c5/rtc_clk.c b/components/esp_hw_support/port/esp32c5/rtc_clk.c index e244ebe18d6..c550c44d0c1 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c5/rtc_clk.c @@ -172,6 +172,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) clk_ll_bbpll_set_config(pll_freq, xtal_freq); /* WAIT CALIBRATION DONE */ while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); // wait for true stop /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); rtc_clk_enable_i2c_ana_master_clock(false); @@ -185,29 +186,60 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) */ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) { - clk_ll_ahb_set_ls_divider(div); - clk_ll_cpu_set_ls_divider(div); + // let f_cpu = f_ahb + clk_ll_cpu_set_divider(div); + clk_ll_ahb_set_divider(div); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(cpu_freq); } static void rtc_clk_cpu_freq_to_8m(void) { - clk_ll_ahb_set_ls_divider(1); - clk_ll_cpu_set_ls_divider(1); + clk_ll_cpu_set_divider(1); + clk_ll_ahb_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(20); } /** - * Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL. + * Switch to PLL_F240M as cpu clock source. * PLL must already be enabled. * @param cpu_freq new CPU frequency */ -static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) -{ - clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz); - clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); +static void rtc_clk_cpu_freq_to_pll_240_mhz(int cpu_freq_mhz) +{ + // f_hp_root = 240MHz + uint32_t cpu_divider = CLK_LL_PLL_240M_FREQ_MHZ / cpu_freq_mhz; + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...) + // let f_ahb = 40MHz + const uint32_t ahb_divider = 6; + assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0)); + clk_ll_ahb_set_divider(ahb_divider); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F240M); + clk_ll_bus_update(); + esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); +} + +/** + * Switch to PLL_F160M as cpu clock source. + * PLL must already be enabled. + * @param cpu_freq new CPU frequency + */ +static void rtc_clk_cpu_freq_to_pll_160_mhz(int cpu_freq_mhz) +{ + // f_hp_root = 160MHz + uint32_t cpu_divider = CLK_LL_PLL_160M_FREQ_MHZ / cpu_freq_mhz; + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...) + // let f_ahb = 40MHz + const uint32_t ahb_divider = 4; + assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0)); + clk_ll_ahb_set_divider(ahb_divider); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F160M); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); } @@ -219,7 +251,14 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou uint32_t real_freq_mhz; uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); - if (freq_mhz <= xtal_freq && freq_mhz != 0) { + // To maintain APB_MAX (40MHz) while lowering CPU frequency when using a 48MHz XTAL, have to let CPU frequnecy be + // 40MHz with PLL_F160M or PLL_F240M clock source. This is a special case, has to handle separately. + if (xtal_freq == SOC_XTAL_FREQ_48M && freq_mhz == 40) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 4; + } else if (freq_mhz <= xtal_freq && freq_mhz != 0) { divider = xtal_freq / freq_mhz; real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */ if (real_freq_mhz != freq_mhz) { @@ -229,21 +268,21 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou source_freq_mhz = xtal_freq; source = SOC_CPU_CLK_SRC_XTAL; - } else if (freq_mhz == 80) { - real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 6; - } else if (freq_mhz == 120) { + } else if (freq_mhz == 240) { real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 4; + source = SOC_CPU_CLK_SRC_PLL_F240M; + source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + divider = 1; } else if (freq_mhz == 160) { real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 3; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 1; + } else if (freq_mhz == 80) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 2; } else { // unsupported frequency return false; @@ -266,21 +305,29 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { + if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) { // We don't turn off the bbpll if some consumers depend on bbpll rtc_clk_bbpll_disable(); } - } else if (config->source == SOC_CPU_CLK_SRC_PLL) { - if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) { + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M) { + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) { rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START); rtc_clk_bbpll_enable(); - rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ); } - rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz); + rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M) { + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) { + rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START); + rtc_clk_bbpll_enable(); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ); + } + rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz); rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); - if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { + if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) { // We don't turn off the bbpll if some consumers depend on bbpll rtc_clk_bbpll_disable(); } @@ -292,17 +339,21 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); uint32_t source_freq_mhz; uint32_t freq_mhz; - uint32_t div = clk_ll_cpu_get_ls_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK - uint32_t hs_div = clk_ll_cpu_get_hs_divider(); + uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK switch (source) { case SOC_CPU_CLK_SRC_XTAL: { source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get(); freq_mhz = source_freq_mhz / div; break; } - case SOC_CPU_CLK_SRC_PLL: { - source_freq_mhz = clk_ll_bbpll_get_freq_mhz(); - freq_mhz = source_freq_mhz / hs_div; + case SOC_CPU_CLK_SRC_PLL_F160M: { + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + freq_mhz = source_freq_mhz / div; + break; + } + case SOC_CPU_CLK_SRC_PLL_F240M: { + source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_RC_FAST: @@ -325,11 +376,12 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) { if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - } else if ( - config->source == SOC_CPU_CLK_SRC_PLL && - s_cur_pll_freq == config->source_freq_mhz - ) { - rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M && + s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) { + rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M && + s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) { + rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); } else { @@ -356,7 +408,8 @@ void rtc_clk_cpu_set_to_default_config(void) void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz) { - rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz); + // TODO: IDF-8641 CPU_MAX_FREQ don't know what to do... pll_240 or pll_160... + rtc_clk_cpu_freq_to_pll_240_mhz(cpu_freq_mhz); clk_ll_cpu_clk_src_lock_release(); } @@ -375,15 +428,19 @@ static uint32_t rtc_clk_ahb_freq_get(void) switch (source) { case SOC_CPU_CLK_SRC_XTAL: soc_root_freq_mhz = rtc_clk_xtal_freq_get(); - divider = clk_ll_ahb_get_ls_divider(); + divider = clk_ll_ahb_get_divider(); + break; + case SOC_CPU_CLK_SRC_PLL_F160M: + soc_root_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = clk_ll_ahb_get_divider(); break; - case SOC_CPU_CLK_SRC_PLL: - soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz(); - divider = clk_ll_ahb_get_hs_divider(); + case SOC_CPU_CLK_SRC_PLL_F240M: + soc_root_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + divider = clk_ll_ahb_get_divider(); break; case SOC_CPU_CLK_SRC_RC_FAST: soc_root_freq_mhz = 20; - divider = clk_ll_ahb_get_ls_divider(); + divider = clk_ll_ahb_get_divider(); break; default: // Unknown SOC_ROOT clock source diff --git a/components/esp_hw_support/port/esp32c5/rtc_clk_init.c b/components/esp_hw_support/port/esp32c5/rtc_clk_init.c index f8c61cda81a..81e452e71a8 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c5/rtc_clk_init.c @@ -79,10 +79,14 @@ void rtc_clk_init(rtc_clk_config_t cfg) REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); - REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, HP_CALI_DBIAS); - REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, LP_CALI_DBIAS); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); + uint32_t hp_cali_dbias = get_act_hp_dbias(); + uint32_t lp_cali_dbias = get_act_lp_dbias(); - clk_ll_rc_fast_tick_conf(); // TODO: IDF-8642 Unnecessary or not? + SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); // XTAL freq determined by efuse, and can be directly informed from register field PCR_CLK_XTAL_FREQ diff --git a/components/esp_hw_support/port/esp32c5/rtc_time.c b/components/esp_hw_support/port/esp32c5/rtc_time.c index ec157f07d18..76e77e06f50 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_time.c +++ b/components/esp_hw_support/port/esp32c5/rtc_time.c @@ -12,6 +12,7 @@ #include "hal/clk_tree_ll.h" #include "hal/timer_ll.h" #include "soc/timer_group_reg.h" +#include "soc/pcr_reg.h" #include "esp_rom_sys.h" #include "assert.h" #include "hal/efuse_hal.h" @@ -23,64 +24,31 @@ __attribute__((unused)) static const char *TAG = "rtc_time"; /* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. * This feature counts the number of XTAL clock cycles within a given number of * RTC_SLOW_CLK cycles. - * - * Slow clock calibration feature has two modes of operation: one-off and cycling. - * In cycling mode (which is enabled by default on SoC reset), counting of XTAL - * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled - * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed - * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is - * enabled using TIMG_RTC_CALI_START bit. */ -/* On ESP32C5, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3 - * 0 or 3: calibrate RC_SLOW clock - * 1: calibrate RC_FAST clock - * 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0 - */ -#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0 -#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1 -#define TIMG_RTC_CALI_CLK_SEL_32K 2 +#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10)) -/** - * @brief Clock calibration function used by rtc_clk_cal - * - * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. - * This feature counts the number of XTAL clock cycles within a given number of - * RTC_SLOW_CLK cycles. - * - * Slow clock calibration feature has two modes of operation: one-off and cycling. - * In cycling mode (which is enabled by default on SoC reset), counting of XTAL - * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled - * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed - * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is - * enabled using TIMG_RTC_CALI_START bit. - * - * @param cal_clk which clock to calibrate - * @param slowclk_cycles number of slow clock cycles to count - * @return number of XTAL clock cycles within the given number of slow clock cycles - */ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); - uint32_t cali_clk_sel = 0; - soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); - soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target(); if (cal_clk == RTC_CAL_RTC_MUX) { - cal_clk = (rtc_cal_sel_t)slow_clk_src; + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { + cal_clk = RTC_CAL_RC_SLOW; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + cal_clk = RTC_CAL_32K_XTAL; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + cal_clk = RTC_CAL_RC32K; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + cal_clk = RTC_CAL_32K_OSC_SLOW; + } } - // TODO: [ESP32C5] IDF-8642 Seems RC_SLOW, RC_FAST can't be calibrated on beta3 - // if (cal_clk == RTC_CAL_RC_FAST) { - // cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST; - // } else if (cal_clk == RTC_CAL_RC_SLOW) { - // cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW; - // } else - { - cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K; - clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk); + if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) { + ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); + return 0; } - /* Enable requested clock (150k clock is always on) */ // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock // Only enable if originally was disabled, and set back to the disable state after calibration is done @@ -90,16 +58,16 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc clk_ll_xtal32k_digi_enable(); } - // bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); - // bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); - // if (cal_clk == RTC_CAL_RC_FAST) { - // if (!rc_fast_enabled) { - // rtc_clk_8m_enable(true); - // } - // if (!dig_rc_fast_enabled) { - // rtc_dig_clk8m_enable(); - // } - // } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC_FAST) { + if (!rc_fast_enabled) { + rtc_clk_8m_enable(true); + } + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_enable(); + } + } bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); @@ -126,22 +94,22 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } /* Prepare calibration */ - // calibration clock source is set by PCR register: PCR_32K_SEL - // REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + REG_SET_FIELD(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk); + if (cal_clk == RTC_CAL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ /* Set timeout reg and expect time delay*/ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); uint32_t expected_freq; - if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles)); + if (cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) { expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; - } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles)); - expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + } else if (cal_clk == RTC_CAL_RC_FAST) { + expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX >> CLK_LL_RC_FAST_TICK_DIV_BITS; } else { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; } uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); @@ -156,12 +124,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE); - // TODO: IDF-8642 Check whether this workaround still need for C5 - // /*The Fosc CLK of calibration circuit is divided by 32. - // So we need to multiply the frequency of the FOSC by 32 times.*/ - // if (cal_clk == RTC_CAL_RC_FAST) { - // cal_val = cal_val >> 5; - // } + /*The Fosc CLK of calibration circuit is divided by a factor, k. + So we need to multiply the frequency of the FOSC by k times.*/ + if (cal_clk == RTC_CAL_RC_FAST) { + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } break; } if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { @@ -176,14 +143,14 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc clk_ll_xtal32k_digi_disable(); } - // if (cal_clk == RTC_CAL_RC_FAST) { - // if (!dig_rc_fast_enabled) { - // rtc_dig_clk8m_disable(); - // } - // if (!rc_fast_enabled) { - // rtc_clk_8m_enable(false); - // } - // } + if (cal_clk == RTC_CAL_RC_FAST) { + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_disable(); + } + if (!rc_fast_enabled) { + rtc_clk_8m_enable(false); + } + } if (cal_clk == RTC_CAL_RC32K) { if (!dig_rc32k_enabled) { @@ -194,11 +161,6 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } } - // Always set back the calibration 32kHz clock selection - if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) { - clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel); - } - return cal_val; } @@ -212,13 +174,13 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); - // TODO: IDF-8642 Check whether this workaround still need for C5 - // /*The Fosc CLK of calibration circuit is divided by 32. - // So we need to divide the calibrate cycles of the FOSC by 32 to - // avoid excessive calibration time.*/ - // if (cal_clk == RTC_CAL_RC_FAST) { - // slowclk_cycles = slowclk_cycles >> 5; - // } + + /*The Fosc CLK of calibration circuit is divided by a factor, k. + So we need to divide the calibrate cycles of the FOSC by k to + avoid excessive calibration time.*/ + if (cal_clk == RTC_CAL_RC_FAST) { + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) { @@ -246,8 +208,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) uint64_t rtc_time_get(void) { - ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet"); - return 0; + return lp_timer_hal_get_cycle_count(); } uint32_t rtc_clk_freq_cal(uint32_t cal_val) diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c index b6c11b8632e..a50e7bec68a 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -347,6 +347,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp bool pmu_sleep_finish(bool dslp) { (void)dslp; + + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c index 70c275a1f96..9ab938f02ae 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -84,8 +84,6 @@ void rtc_clk_init(rtc_clk_config_t cfg) SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - clk_ll_rc_fast_tick_conf(); - soc_xtal_freq_t xtal_freq = cfg.xtal_freq; esp_rom_output_tx_wait_idle(0); rtc_clk_xtal_freq_update(xtal_freq); diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index 40b535eefd6..8e31485e1df 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc /* Prepare calibration */ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ @@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } } else { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; @@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (cal_clk == RTC_CAL_RC_FAST) { - cal_val = cal_val >> 5; + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } @@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) avoid excessive calibration time.*/ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (cal_clk == RTC_CAL_RC_FAST) { - slowclk_cycles = slowclk_cycles >> 5; + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c index d456aee7641..fcac148c6a9 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c @@ -52,8 +52,6 @@ void rtc_clk_init(rtc_clk_config_t cfg) SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - clk_ll_rc_fast_tick_conf(); - soc_xtal_freq_t xtal_freq = cfg.xtal_freq; esp_rom_output_tx_wait_idle(0); rtc_clk_xtal_freq_update(xtal_freq); diff --git a/components/esp_hw_support/port/esp32h2/rtc_time.c b/components/esp_hw_support/port/esp32h2/rtc_time.c index 395be4dc4ab..7db712d7a61 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_time.c +++ b/components/esp_hw_support/port/esp32h2/rtc_time.c @@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc /* Prepare calibration */ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ @@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_8M_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { + expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } } else { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; @@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { - cal_val = cal_val >> 5; + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } @@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) avoid excessive calibration time.*/ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { - slowclk_cycles = slowclk_cycles >> 5; + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 0b3d5cbaf28..1f86803d493 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -333,6 +333,9 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp) pmu_sleep_shutdown_ldo(); } + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + unsigned chip_version = efuse_hal_chip_revision(); if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M diff --git a/components/esp_hw_support/port/esp_clk_tree_common.c b/components/esp_hw_support/port/esp_clk_tree_common.c index 0bc2bfe5319..cf5a2eece1a 100644 --- a/components/esp_hw_support/port/esp_clk_tree_common.c +++ b/components/esp_hw_support/port/esp_clk_tree_common.c @@ -41,6 +41,9 @@ static esp_clk_tree_calibrated_freq_t s_calibrated_freq = {}; #define DEFAULT_32K_CLK_CAL_CYCLES 100 /* Number of cycles for RC_FAST calibration */ #define DEFAULT_RC_FAST_CAL_CYCLES 10000 // RC_FAST has a higher frequency, therefore, requires more cycles to get an accurate value + // Usually we calibrate on the divider of the RC_FAST clock, the cal_cycles is divided by + // the divider factor internally in rtc_clk_cal, so the time to spend on calibrating RC_FAST + // is always (10000 / f_rc_fast) /** @@ -187,6 +190,10 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec #if SOC_CLK_LP_FAST_SUPPORT_LP_PLL case SOC_RTC_FAST_CLK_SRC_LP_PLL: return clk_ll_lp_pll_get_freq_mhz() * MHZ; +#endif +#if SOC_CLK_LP_FAST_SUPPORT_XTAL + case SOC_RTC_FAST_CLK_SRC_XTAL: + return clk_hal_xtal_get_freq_mhz() * MHZ; #endif default: // Invalid clock source diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index a395b606192..b7e85dae37c 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -17,10 +17,6 @@ components/esp_hw_support/test_apps/dma2d: components/esp_hw_support/test_apps/esp_hw_support_unity_tests: disable: - if: SOC_GPSPI_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8972 components/esp_hw_support/test_apps/etm: disable: diff --git a/components/esp_hw_support/test_apps/dma/pytest_dma.py b/components/esp_hw_support/test_apps/dma/pytest_dma.py index cc78dd5f0ec..0e863284690 100644 --- a/components/esp_hw_support/test_apps/dma/pytest_dma.py +++ b/components/esp_hw_support/test_apps/dma/pytest_dma.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32c2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py index a96369107b0..303f5bc685e 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8972 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py b/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py index 817b6188c2e..384dd05fe3a 100644 --- a/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py +++ b/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - from typing import Any import pytest @@ -33,6 +32,7 @@ def test_rtc_no_xtal32k(dut: Dut) -> None: @pytest.mark.generic @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c6', 'esp32h2', 'esp32p4'], reason='c6/h2/p4 support TBD') # TODO: IDF-8973 +# TODO: [ESP32P4] IDF-8973 [ESP32C5] IDF-10309 +@pytest.mark.temp_skip_ci(targets=['esp32c6', 'esp32h2', 'esp32p4', 'esp32c5'], reason='c6/h2/p4/c5 support TBD') def test_rtc_calib(case_tester: Any) -> None: case_tester.run_all_multi_stage_cases() diff --git a/components/esp_lcd/include/esp_lcd_io_spi.h b/components/esp_lcd/include/esp_lcd_io_spi.h index 43e1f571295..6781c6a428a 100644 --- a/components/esp_lcd/include/esp_lcd_io_spi.h +++ b/components/esp_lcd/include/esp_lcd_io_spi.h @@ -29,6 +29,8 @@ typedef struct { void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ + uint8_t cs_ena_pretrans; /*!< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16) */ + uint8_t cs_ena_posttrans; /*!< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16) */ struct { unsigned int dc_high_on_cmd: 1; /*!< If enabled, DC level = 1 indicates command transfer */ unsigned int dc_low_on_data: 1; /*!< If enabled, DC level = 0 indicates color data transfer */ diff --git a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c index c1b9bde53d2..9586c84ab37 100644 --- a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c @@ -50,6 +50,8 @@ typedef struct { size_t num_trans_inflight; // Number of transactions that are undergoing (the descriptor not recycled yet) int lcd_cmd_bits; // Bit width of LCD command int lcd_param_bits; // Bit width of LCD parameter + uint8_t cs_ena_pretrans; // Amount of SPI bit-cycles the cs should be activated before the transmission (0-16) + uint8_t cs_ena_posttrans; // Amount of SPI bit-cycles the cs should stay active after the transmission (0-16) struct { unsigned int dc_cmd_level: 1; // Indicates the level of DC line when transferring command unsigned int dc_data_level: 1; // Indicates the level of DC line when transferring color data @@ -82,6 +84,8 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p .queue_size = io_config->trans_queue_depth, .pre_cb = lcd_spi_pre_trans_cb, // pre-transaction callback, mainly control DC gpio level .post_cb = lcd_spi_post_trans_color_cb, // post-transaction, where we invoke user registered "on_color_trans_done()" + .cs_ena_pretrans = io_config->cs_ena_pretrans, + .cs_ena_posttrans = io_config->cs_ena_posttrans, }; ret = spi_bus_add_device((spi_host_device_t)bus, &devcfg, &spi_panel_io->spi_dev); ESP_GOTO_ON_ERROR(ret, err, TAG, "adding spi device to bus failed"); diff --git a/components/esp_lcd/test_apps/.build-test-rules.yml b/components/esp_lcd/test_apps/.build-test-rules.yml index 998917f0ab9..d6308cf692b 100644 --- a/components/esp_lcd/test_apps/.build-test-rules.yml +++ b/components/esp_lcd/test_apps/.build-test-rules.yml @@ -52,7 +52,3 @@ components/esp_lcd/test_apps/spi_lcd: - esp_driver_spi disable: - if: SOC_GPSPI_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8975 diff --git a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h index ec4600376d8..9ce7d5224e8 100644 --- a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,20 @@ extern "C" { #define TEST_LCD_DC_GPIO 1 #define TEST_LCD_PCLK_GPIO 2 #define TEST_LCD_DATA0_GPIO 4 +#elif CONFIG_IDF_TARGET_ESP32P4 +#define TEST_LCD_BK_LIGHT_GPIO 23 +#define TEST_LCD_RST_GPIO 6 +#define TEST_LCD_CS_GPIO 4 +#define TEST_LCD_DC_GPIO 3 +#define TEST_LCD_PCLK_GPIO 2 +#define TEST_LCD_DATA0_GPIO 32 +#define TEST_LCD_DATA1_GPIO 33 +#define TEST_LCD_DATA2_GPIO 22 +#define TEST_LCD_DATA3_GPIO 8 +#define TEST_LCD_DATA4_GPIO 21 +#define TEST_LCD_DATA5_GPIO 53 +#define TEST_LCD_DATA6_GPIO 20 +#define TEST_LCD_DATA7_GPIO 5 #else #define TEST_LCD_BK_LIGHT_GPIO 18 #define TEST_LCD_RST_GPIO 5 diff --git a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py index f2ad352216e..2cdeaf11e8a 100644 --- a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py +++ b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8975 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( diff --git a/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py b/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py index de7bed11eeb..972bee544b4 100644 --- a/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py +++ b/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py @@ -1,13 +1,12 @@ # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.ethernet -def test_esp_netif(dut: Dut) -> None: +def test_esp_netif_vfs_l2tp(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('\n') dut.expect_exact('Enter test for running.') diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index a2c2fc0f765..6dcd162b61e 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -6,6 +6,7 @@ @pytest.mark.generic @pytest.mark.supported_targets +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not supported yet') # TODO: [ESP32C5] IDF-8643, IDF-10310 @pytest.mark.parametrize('config', [ 'default', 'slp_iram_opt', @@ -45,9 +46,11 @@ def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: # power down CPU and TOP domain in auto-lightsleep +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not supported yet') # TODO: [ESP32C5] IDF-8643, IDF-10310 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 9a97104f9a4..526b1919386 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -3,7 +3,8 @@ idf_build_get_property(target IDF_TARGET) set(target_folder "${target}") set(include_dirs "include" - "include/${target_folder}" + "${target_folder}/include" + "${target_folder}/include/${target_folder}" "${target_folder}") set(private_required_comp "") @@ -17,9 +18,6 @@ if(target STREQUAL "linux") "${target}/esp_rom_md5.c" "${target}/esp_rom_efuse.c") else() - if(CONFIG_IDF_TARGET_ESP32C5) - list(APPEND include_dirs "include/${target_folder}/..") - endif() list(APPEND sources "patches/esp_rom_crc.c" "patches/esp_rom_uart.c" "patches/esp_rom_spiflash.c" @@ -129,10 +127,6 @@ if(BOOTLOADER_BUILD) elseif(target STREQUAL "esp32s2") rom_linker_script("spiflash_legacy") - - elseif(target STREQUAL "esp32c6") - # The linking of the bootloader needs to use the rom_i2c_writeReg_Mask in esp32c6.rom.phy.ld - rom_linker_script("phy") endif() if(CONFIG_ESP_ROM_HAS_NEWLIB) diff --git a/components/esp_rom/include/esp32/rom/aes.h b/components/esp_rom/esp32/include/esp32/rom/aes.h similarity index 58% rename from components/esp_rom/include/esp32/rom/aes.h rename to components/esp_rom/esp32/include/esp32/rom/aes.h index bbe13d22e47..a517a350a81 100644 --- a/components/esp_rom/include/esp32/rom/aes.h +++ b/components/esp_rom/esp32/include/esp32/rom/aes.h @@ -5,19 +5,11 @@ use the wrapper functions in esp32/aes.h instead. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_AES_H_ #define _ROM_AES_H_ diff --git a/components/esp_rom/include/esp32/rom/bigint.h b/components/esp_rom/esp32/include/esp32/rom/bigint.h similarity index 67% rename from components/esp_rom/include/esp32/rom/bigint.h rename to components/esp_rom/esp32/include/esp32/rom/bigint.h index 97ad72202a3..16ed4dc1c2c 100644 --- a/components/esp_rom/include/esp32/rom/bigint.h +++ b/components/esp_rom/esp32/include/esp32/rom/bigint.h @@ -5,19 +5,11 @@ use the wrapper functions in hwcrypto/mpi.h instead. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_BIGINT_H_ #define _ROM_BIGINT_H_ diff --git a/components/esp_rom/include/esp32/rom/cache.h b/components/esp_rom/esp32/include/esp32/rom/cache.h similarity index 100% rename from components/esp_rom/include/esp32/rom/cache.h rename to components/esp_rom/esp32/include/esp32/rom/cache.h diff --git a/components/esp_rom/include/esp32/rom/crc.h b/components/esp_rom/esp32/include/esp32/rom/crc.h similarity index 87% rename from components/esp_rom/include/esp32/rom/crc.h rename to components/esp_rom/esp32/include/esp32/rom/crc.h index a570361176b..16c0e0ed3e0 100644 --- a/components/esp_rom/include/esp32/rom/crc.h +++ b/components/esp_rom/esp32/include/esp32/rom/crc.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef ROM_CRC_H #define ROM_CRC_H diff --git a/components/esp_rom/include/esp32/rom/efuse.h b/components/esp_rom/esp32/include/esp32/rom/efuse.h similarity index 100% rename from components/esp_rom/include/esp32/rom/efuse.h rename to components/esp_rom/esp32/include/esp32/rom/efuse.h diff --git a/components/esp_rom/include/esp32/rom/ets_sys.h b/components/esp_rom/esp32/include/esp32/rom/ets_sys.h similarity index 97% rename from components/esp_rom/include/esp32/rom/ets_sys.h rename to components/esp_rom/esp32/include/esp32/rom/ets_sys.h index 549db8ffc63..eb73b897955 100644 --- a/components/esp_rom/include/esp32/rom/ets_sys.h +++ b/components/esp_rom/esp32/include/esp32/rom/ets_sys.h @@ -64,11 +64,11 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ /** - * @brief Start the Espressif Task Scheduler, which is an infinit loop. Please do not add code after it. + * @brief Start the Espressif Task Scheduler, which is an infinite loop. Please do not add code after it. * * @param none * @@ -88,9 +88,9 @@ void ets_run(void); void ets_set_idle_cb(ets_idle_cb_t func, void *arg); /** - * @brief Init a task with processer, priority, queue to receive Event, queue length. + * @brief Init a task with processor, priority, queue to receive Event, queue length. * - * @param ETSTask task : The task processer. + * @param ETSTask task : The task processor. * * @param uint8_t prio : Task priority, 0-31, bigger num with high priority, one priority with one task. * @@ -128,7 +128,7 @@ ETS_STATUS ets_post(uint8_t prio, ETSSignal sig, ETSParam par); * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -230,7 +230,7 @@ int ets_printf(const char *fmt, ...); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -240,7 +240,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -283,7 +283,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32/rom/gpio.h b/components/esp_rom/esp32/include/esp32/rom/gpio.h similarity index 97% rename from components/esp_rom/include/esp32/rom/gpio.h rename to components/esp_rom/esp32/include/esp32/rom/gpio.h index 62df27f02cf..6a6b458718a 100644 --- a/components/esp_rom/include/esp32/rom/gpio.h +++ b/components/esp_rom/esp32/include/esp32/rom/gpio.h @@ -62,7 +62,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ @@ -79,7 +79,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32/rom/libc_stubs.h b/components/esp_rom/esp32/include/esp32/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32/rom/libc_stubs.h rename to components/esp_rom/esp32/include/esp32/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32/rom/lldesc.h b/components/esp_rom/esp32/include/esp32/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32/rom/lldesc.h rename to components/esp_rom/esp32/include/esp32/rom/lldesc.h diff --git a/components/esp_rom/include/esp32/rom/md5_hash.h b/components/esp_rom/esp32/include/esp32/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32/rom/md5_hash.h rename to components/esp_rom/esp32/include/esp32/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32/rom/rsa_pss.h b/components/esp_rom/esp32/include/esp32/rom/rsa_pss.h similarity index 100% rename from components/esp_rom/include/esp32/rom/rsa_pss.h rename to components/esp_rom/esp32/include/esp32/rom/rsa_pss.h diff --git a/components/esp_rom/include/esp32/rom/rtc.h b/components/esp_rom/esp32/include/esp32/rom/rtc.h similarity index 99% rename from components/esp_rom/include/esp32/rom/rtc.h rename to components/esp_rom/esp32/include/esp32/rom/rtc.h index 101b4bf56b5..a39b2f267a4 100644 --- a/components/esp_rom/include/esp32/rom/rtc.h +++ b/components/esp_rom/esp32/include/esp32/rom/rtc.h @@ -85,7 +85,7 @@ typedef enum { TGWDT_CPU_RESET = 11, /**<11, Time Group reset CPU*/ SW_CPU_RESET = 12, /**<12, Software reset CPU*/ RTCWDT_CPU_RESET = 13, /**<13, RTC Watch dog Reset CPU*/ - EXT_CPU_RESET = 14, /**<14, for APP CPU, reseted by PRO CPU*/ + EXT_CPU_RESET = 14, /**<14, for APP CPU, reset by PRO CPU*/ RTCWDT_BROWN_OUT_RESET = 15, /**<15, Reset when the vdd voltage is not stable*/ RTCWDT_RTC_RESET = 16 /**<16, RTC Watch dog reset digital core and rtc module*/ } RESET_REASON; diff --git a/components/esp_rom/include/esp32/rom/secure_boot.h b/components/esp_rom/esp32/include/esp32/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32/rom/secure_boot.h rename to components/esp_rom/esp32/include/esp32/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32/rom/sha.h b/components/esp_rom/esp32/include/esp32/rom/sha.h similarity index 62% rename from components/esp_rom/include/esp32/rom/sha.h rename to components/esp_rom/esp32/include/esp32/rom/sha.h index f43c19d16ac..39d0578592d 100644 --- a/components/esp_rom/include/esp32/rom/sha.h +++ b/components/esp_rom/esp32/include/esp32/rom/sha.h @@ -6,19 +6,11 @@ esp_sha_lock_memory_block() functions in esp32/sha.h to ensure exclusive access. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_SHA_H_ #define _ROM_SHA_H_ diff --git a/components/esp_rom/include/esp32/rom/spi_flash.h b/components/esp_rom/esp32/include/esp32/rom/spi_flash.h similarity index 100% rename from components/esp_rom/include/esp32/rom/spi_flash.h rename to components/esp_rom/esp32/include/esp32/rom/spi_flash.h diff --git a/components/esp_rom/esp32/include/esp32/rom/tbconsole.h b/components/esp_rom/esp32/include/esp32/rom/tbconsole.h new file mode 100644 index 00000000000..cece0a83a4a --- /dev/null +++ b/components/esp_rom/esp32/include/esp32/rom/tbconsole.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _ROM_TBCONSOLE_H_ +#define _ROM_TBCONSOLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void start_tb_console(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_TBCONSOLE_H_ */ diff --git a/components/esp_rom/include/esp32/rom/tjpgd.h b/components/esp_rom/esp32/include/esp32/rom/tjpgd.h similarity index 94% rename from components/esp_rom/include/esp32/rom/tjpgd.h rename to components/esp_rom/esp32/include/esp32/rom/tjpgd.h index 3c110a13028..0a44ebe2fbe 100644 --- a/components/esp_rom/include/esp32/rom/tjpgd.h +++ b/components/esp_rom/esp32/include/esp32/rom/tjpgd.h @@ -71,7 +71,7 @@ struct JDEC { BYTE msx, msy; /* MCU size in unit of block (width, height) */ BYTE qtid[3]; /* Quantization table ID of each component */ SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ + WORD nrst; /* Restart interval */ UINT width, height; /* Size of the input image (pixel) */ BYTE* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ WORD* huffcode[2][2]; /* Huffman code word tables [id][dcac] */ @@ -80,9 +80,9 @@ struct JDEC { void* workbuf; /* Working buffer for IDCT and RGB output */ BYTE* mcubuf; /* Working buffer for the MCU */ void* pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT sz_pool; /* Size of memory pool (bytes available) */ UINT (*infunc)(JDEC*, BYTE*, UINT);/* Pointer to jpeg stream input function */ - void* device; /* Pointer to I/O device identifiler for the session */ + void* device; /* Pointer to I/O device identifier for the session */ }; diff --git a/components/esp_rom/include/esp32/rom/uart.h b/components/esp_rom/esp32/include/esp32/rom/uart.h similarity index 100% rename from components/esp_rom/include/esp32/rom/uart.h rename to components/esp_rom/esp32/include/esp32/rom/uart.h diff --git a/components/esp_rom/include/esp32c2/rom/apb_backup_dma.h b/components/esp_rom/esp32c2/include/esp32c2/rom/apb_backup_dma.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/apb_backup_dma.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/apb_backup_dma.h diff --git a/components/esp_rom/include/esp32c2/rom/cache.h b/components/esp_rom/esp32c2/include/esp32c2/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32c2/rom/cache.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/cache.h index 51e38469bed..39d6bbf9f76 100644 --- a/components/esp_rom/include/esp32c2/rom/cache.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/cache.h @@ -445,7 +445,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32c2/rom/crc.h b/components/esp_rom/esp32c2/include/esp32c2/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/crc.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/crc.h diff --git a/components/esp_rom/include/esp32c2/rom/ecdsa.h b/components/esp_rom/esp32c2/include/esp32c2/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/ecdsa.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32c2/rom/efuse.h b/components/esp_rom/esp32c2/include/esp32c2/rom/efuse.h similarity index 98% rename from components/esp_rom/include/esp32c2/rom/efuse.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/efuse.h index d4f5f8f3900..bb838a67532 100644 --- a/components/esp_rom/include/esp32c2/rom/efuse.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/efuse.h @@ -39,7 +39,7 @@ typedef enum { } ets_efuse_block_t; /** - * @brief set timing accroding the apb clock, so no read error or write error happens. + * @brief set timing according the apb clock, so no read error or write error happens. * * @param clock: apb clock in HZ, only accept 5M(in FPGA), 10M(in FPGA), 20M, 40M, 80M. * @@ -162,7 +162,7 @@ bool ets_efuse_download_modes_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32c2/rom/esp_flash.h b/components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/esp_flash.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32c2/rom/ets_sys.h b/components/esp_rom/esp32c2/include/esp32c2/rom/ets_sys.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/ets_sys.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/ets_sys.h diff --git a/components/esp_rom/include/esp32c2/rom/gpio.h b/components/esp_rom/esp32c2/include/esp32c2/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32c2/rom/gpio.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/gpio.h index 1c4a803d142..6cd67cf964e 100644 --- a/components/esp_rom/include/esp32c2/rom/gpio.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/gpio.h @@ -57,7 +57,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32c2/rom/libc_stubs.h b/components/esp_rom/esp32c2/include/esp32c2/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/libc_stubs.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32c2/rom/lldesc.h b/components/esp_rom/esp32c2/include/esp32c2/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/lldesc.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/lldesc.h diff --git a/components/esp_rom/include/esp32c2/rom/rom_layout.h b/components/esp_rom/esp32c2/include/esp32c2/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/rom_layout.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32c2/rom/rtc.h b/components/esp_rom/esp32c2/include/esp32c2/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/rtc.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/rtc.h diff --git a/components/esp_rom/include/esp32c2/rom/secure_boot.h b/components/esp_rom/esp32c2/include/esp32c2/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/secure_boot.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32c2/rom/sha.h b/components/esp_rom/esp32c2/include/esp32c2/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32c2/rom/sha.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/sha.h diff --git a/components/esp_rom/include/esp32c2/rom/spi_flash.h b/components/esp_rom/esp32c2/include/esp32c2/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32c2/rom/spi_flash.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/spi_flash.h index 4c03ad36e23..f61a9e8d0bc 100644 --- a/components/esp_rom/include/esp32c2/rom/spi_flash.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/spi_flash.h @@ -434,7 +434,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32c2/rom/uart.h b/components/esp_rom/esp32c2/include/esp32c2/rom/uart.h similarity index 98% rename from components/esp_rom/include/esp32c2/rom/uart.h rename to components/esp_rom/esp32c2/include/esp32c2/rom/uart.h index 454e0d83a11..818e291fd34 100644 --- a/components/esp_rom/include/esp32c2/rom/uart.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -263,7 +263,7 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ diff --git a/components/esp_rom/include/esp32c3/rom/aes.h b/components/esp_rom/esp32c3/include/esp32c3/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/aes.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/aes.h diff --git a/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h b/components/esp_rom/esp32c3/include/esp32c3/rom/apb_backup_dma.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/apb_backup_dma.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/apb_backup_dma.h diff --git a/components/esp_rom/include/esp32c3/rom/bigint.h b/components/esp_rom/esp32c3/include/esp32c3/rom/bigint.h similarity index 54% rename from components/esp_rom/include/esp32c3/rom/bigint.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/bigint.h index b63172ea7f7..fbcfd46d81c 100644 --- a/components/esp_rom/include/esp32c3/rom/bigint.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/bigint.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_BIGINT_H_ #define _ROM_BIGINT_H_ diff --git a/components/esp_rom/include/esp32c3/rom/cache.h b/components/esp_rom/esp32c3/include/esp32c3/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32c3/rom/cache.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/cache.h index 148f47427fe..2711cc37646 100644 --- a/components/esp_rom/include/esp32c3/rom/cache.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/cache.h @@ -605,7 +605,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32c3/rom/crc.h b/components/esp_rom/esp32c3/include/esp32c3/rom/crc.h similarity index 81% rename from components/esp_rom/include/esp32c3/rom/crc.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/crc.h index e683f4fd419..549db7158c8 100644 --- a/components/esp_rom/include/esp32c3/rom/crc.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/crc.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef ROM_CRC_H #define ROM_CRC_H diff --git a/components/esp_rom/include/esp32c3/rom/digital_signature.h b/components/esp_rom/esp32c3/include/esp32c3/rom/digital_signature.h similarity index 89% rename from components/esp_rom/include/esp32c3/rom/digital_signature.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/digital_signature.h index 54c01681d40..0d8778101e5 100644 --- a/components/esp_rom/include/esp32c3/rom/digital_signature.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/digital_signature.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32c3/rom/efuse.h b/components/esp_rom/esp32c3/include/esp32c3/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32c3/rom/efuse.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/efuse.h index 912af40d96c..cf2767b7d5b 100644 --- a/components/esp_rom/include/esp32c3/rom/efuse.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/efuse.h @@ -55,7 +55,7 @@ typedef enum { } ets_efuse_block_t; /** - * @brief set timing accroding the apb clock, so no read error or write error happens. + * @brief set timing according the apb clock, so no read error or write error happens. * * @param clock: apb clock in HZ, only accept 5M(in FPGA), 10M(in FPGA), 20M, 40M, 80M. * @@ -208,7 +208,7 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32c3/rom/esp_flash.h b/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h similarity index 64% rename from components/esp_rom/include/esp32c3/rom/esp_flash.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h index 40e5872c090..3b1c97b2e84 100644 --- a/components/esp_rom/include/esp32c3/rom/esp_flash.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32c3/rom/ets_sys.h b/components/esp_rom/esp32c3/include/esp32c3/rom/ets_sys.h similarity index 97% rename from components/esp_rom/include/esp32c3/rom/ets_sys.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/ets_sys.h index 06b3b47d8c2..96ade75932a 100644 --- a/components/esp_rom/include/esp32c3/rom/ets_sys.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/ets_sys.h @@ -61,7 +61,7 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ @@ -80,7 +80,7 @@ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callbac * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -125,7 +125,7 @@ int ets_printf(const char *fmt, ...); uint8_t ets_get_printf_channel(void); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -135,7 +135,7 @@ uint8_t ets_get_printf_channel(void); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -178,7 +178,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32c3/rom/gpio.h b/components/esp_rom/esp32c3/include/esp32c3/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32c3/rom/gpio.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/gpio.h index 39c2564f3b2..8bbb1ce8eb5 100644 --- a/components/esp_rom/include/esp32c3/rom/gpio.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/gpio.h @@ -57,7 +57,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32s2/rom/hmac.h b/components/esp_rom/esp32c3/include/esp32c3/rom/hmac.h similarity index 71% rename from components/esp_rom/include/esp32s2/rom/hmac.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/hmac.h index f5f82d5b239..7ec5dfc3c2d 100644 --- a/components/esp_rom/include/esp32s2/rom/hmac.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/hmac.h @@ -1,16 +1,8 @@ -// Copyright 2018 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_HMAC_H_ #define _ROM_HMAC_H_ diff --git a/components/esp_rom/include/esp32c3/rom/libc_stubs.h b/components/esp_rom/esp32c3/include/esp32c3/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/libc_stubs.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32c3/rom/lldesc.h b/components/esp_rom/esp32c3/include/esp32c3/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/lldesc.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/lldesc.h diff --git a/components/esp_rom/include/esp32c3/rom/md5_hash.h b/components/esp_rom/esp32c3/include/esp32c3/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/md5_hash.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32c3/rom/rom_layout.h b/components/esp_rom/esp32c3/include/esp32c3/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/rom_layout.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32c3/rom/rsa_pss.h b/components/esp_rom/esp32c3/include/esp32c3/rom/rsa_pss.h similarity index 54% rename from components/esp_rom/include/esp32c3/rom/rsa_pss.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/rsa_pss.h index 4a838071e76..90bf9de64fb 100644 --- a/components/esp_rom/include/esp32c3/rom/rsa_pss.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/rsa_pss.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_RSA_PSS_H_ #define _ROM_RSA_PSS_H_ diff --git a/components/esp_rom/include/esp32c3/rom/rtc.h b/components/esp_rom/esp32c3/include/esp32c3/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/rtc.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/rtc.h diff --git a/components/esp_rom/include/esp32c3/rom/secure_boot.h b/components/esp_rom/esp32c3/include/esp32c3/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/secure_boot.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32c3/rom/sha.h b/components/esp_rom/esp32c3/include/esp32c3/rom/sha.h similarity index 65% rename from components/esp_rom/include/esp32c3/rom/sha.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/sha.h index 54b1b21676a..1ed5555e849 100644 --- a/components/esp_rom/include/esp32c3/rom/sha.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/sha.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_SHA_H_ #define _ROM_SHA_H_ diff --git a/components/esp_rom/include/esp32c3/rom/spi_flash.h b/components/esp_rom/esp32c3/include/esp32c3/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32c3/rom/spi_flash.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/spi_flash.h index 5862ee724bc..1fe10d33950 100644 --- a/components/esp_rom/include/esp32c3/rom/spi_flash.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/spi_flash.h @@ -428,7 +428,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32c3/rom/tjpgd.h b/components/esp_rom/esp32c3/include/esp32c3/rom/tjpgd.h similarity index 94% rename from components/esp_rom/include/esp32c3/rom/tjpgd.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/tjpgd.h index 80d346a1cb1..56e17c62ac2 100644 --- a/components/esp_rom/include/esp32c3/rom/tjpgd.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/tjpgd.h @@ -71,7 +71,7 @@ struct JDEC { BYTE msx, msy; /* MCU size in unit of block (width, height) */ BYTE qtid[3]; /* Quantization table ID of each component */ SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ + WORD nrst; /* Restart interval */ UINT width, height; /* Size of the input image (pixel) */ BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */ @@ -80,9 +80,9 @@ struct JDEC { void *workbuf; /* Working buffer for IDCT and RGB output */ BYTE *mcubuf; /* Working buffer for the MCU */ void *pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT sz_pool; /* Size of memory pool (bytes available) */ UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */ - void *device; /* Pointer to I/O device identifiler for the session */ + void *device; /* Pointer to I/O device identifier for the session */ }; diff --git a/components/esp_rom/include/esp32c3/rom/uart.h b/components/esp_rom/esp32c3/include/esp32c3/rom/uart.h similarity index 98% rename from components/esp_rom/include/esp32c3/rom/uart.h rename to components/esp_rom/esp32c3/include/esp32c3/rom/uart.h index a4fbd52077f..fcbe425fc18 100644 --- a/components/esp_rom/include/esp32c3/rom/uart.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -253,7 +253,7 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ diff --git a/components/esp_rom/esp32c5/Kconfig.soc_caps.in b/components/esp_rom/esp32c5/Kconfig.soc_caps.in index 98c3d777162..01399dcf91a 100644 --- a/components/esp_rom/esp32c5/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c5/Kconfig.soc_caps.in @@ -47,6 +47,14 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + +config ESP_ROM_MULTI_HEAP_WALK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c5/esp_rom_caps.h b/components/esp_rom/esp32c5/esp_rom_caps.h index 40495fae97a..a2692cf2b62 100644 --- a/components/esp_rom/esp32c5/esp_rom_caps.h +++ b/components/esp_rom/esp32c5/esp_rom_caps.h @@ -17,6 +17,8 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() +#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs TODO: IDF-10110 need refactor diff --git a/components/esp_rom/include/esp32c5/rom/aes.h b/components/esp_rom/esp32c5/include/esp32c5/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/aes.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/aes.h diff --git a/components/esp_rom/include/esp32c5/rom/bigint.h b/components/esp_rom/esp32c5/include/esp32c5/rom/bigint.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/bigint.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/bigint.h diff --git a/components/esp_rom/include/esp32c5/rom/cache.h b/components/esp_rom/esp32c5/include/esp32c5/rom/cache.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/cache.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/cache.h diff --git a/components/esp_rom/include/esp32c5/rom/crc.h b/components/esp_rom/esp32c5/include/esp32c5/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/crc.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/crc.h diff --git a/components/esp_rom/include/esp32c5/rom/digital_signature.h b/components/esp_rom/esp32c5/include/esp32c5/rom/digital_signature.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/digital_signature.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/digital_signature.h diff --git a/components/esp_rom/include/esp32c5/rom/ecdsa.h b/components/esp_rom/esp32c5/include/esp32c5/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/ecdsa.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32c5/rom/efuse.h b/components/esp_rom/esp32c5/include/esp32c5/rom/efuse.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/efuse.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/efuse.h diff --git a/components/esp_rom/include/esp32c5/rom/esp_flash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/esp_flash.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32c5/rom/ets_sys.h b/components/esp_rom/esp32c5/include/esp32c5/rom/ets_sys.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/ets_sys.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/ets_sys.h diff --git a/components/esp_rom/include/esp32c5/rom/gpio.h b/components/esp_rom/esp32c5/include/esp32c5/rom/gpio.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/gpio.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/gpio.h diff --git a/components/esp_rom/include/esp32c5/rom/hmac.h b/components/esp_rom/esp32c5/include/esp32c5/rom/hmac.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/hmac.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/hmac.h diff --git a/components/esp_rom/include/esp32c5/rom/libc_stubs.h b/components/esp_rom/esp32c5/include/esp32c5/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/libc_stubs.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32c5/rom/lldesc.h b/components/esp_rom/esp32c5/include/esp32c5/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/lldesc.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/lldesc.h diff --git a/components/esp_rom/include/esp32c5/rom/md5_hash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/md5_hash.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32c5/rom/opi_flash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/opi_flash.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/opi_flash.h diff --git a/components/esp_rom/include/esp32c5/rom/rom_layout.h b/components/esp_rom/esp32c5/include/esp32c5/rom/rom_layout.h similarity index 85% rename from components/esp_rom/include/esp32c5/rom/rom_layout.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/rom_layout.h index e3796e50ca1..c6d9fa04810 100644 --- a/components/esp_rom/include/esp32c5/rom/rom_layout.h +++ b/components/esp_rom/esp32c5/include/esp32c5/rom/rom_layout.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ extern "C" { #endif +#define CORE_NUM 1 #define SUPPORT_BTDM 0 #define SUPPORT_BTBB 0 #define SUPPORT_WIFI 1 @@ -28,6 +29,10 @@ typedef struct { void *dram0_rtos_reserved_start; void *stack_sentry; void *stack; +#if (CORE_NUM == 2) + void *stack_sentry_app; + void *stack_app; +#endif #if SUPPORT_BTDM void *data_start_btdm; @@ -58,6 +63,7 @@ typedef struct { void *data_end_interface_net80211; void *bss_start_interface_net80211; void *bss_end_interface_net80211; + void *dram_start_pp; void *dram_end_pp; void *data_start_interface_pp; @@ -83,16 +89,15 @@ typedef struct { #if SUPPORT_USB_DWCOTG void *dram_start_usb_dwcotg_rom; void *dram_end_usb_dwcotg_rom; -#else - //Two reserved members are defined here, so the structure will not be broken, - //please keep in mind that there is no memory can be released between - //dram_start_usb_reserved_rom ~ dram_end_usb_reserved_rom. - void *dram_start_usb_reserved_rom; - void *dram_end_usb_reserved_rom; #endif void *dram_start_uart_rom; void *dram_end_uart_rom; + + void *eh_frame_vaddr_rom; + void *eh_frame_hdr_vaddr_rom; + + void *drom_start; } ets_rom_layout_t; extern const ets_rom_layout_t *const ets_rom_layout_p; diff --git a/components/esp_rom/include/esp32c5/rom/rsa_pss.h b/components/esp_rom/esp32c5/include/esp32c5/rom/rsa_pss.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/rsa_pss.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/rsa_pss.h diff --git a/components/esp_rom/include/esp32c5/rom/rtc.h b/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/rtc.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h diff --git a/components/esp_rom/include/esp32c5/rom/secure_boot.h b/components/esp_rom/esp32c5/include/esp32c5/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/secure_boot.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32c5/rom/sha.h b/components/esp_rom/esp32c5/include/esp32c5/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/sha.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/sha.h diff --git a/components/esp_rom/include/esp32c5/rom/spi_flash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/spi_flash.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/spi_flash.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/spi_flash.h diff --git a/components/esp_rom/include/esp32c5/rom/tjpgd.h b/components/esp_rom/esp32c5/include/esp32c5/rom/tjpgd.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/tjpgd.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/tjpgd.h diff --git a/components/esp_rom/include/esp32c5/rom/uart.h b/components/esp_rom/esp32c5/include/esp32c5/rom/uart.h similarity index 100% rename from components/esp_rom/include/esp32c5/rom/uart.h rename to components/esp_rom/esp32c5/include/esp32c5/rom/uart.h diff --git a/components/esp_rom/include/esp32c6/rom/aes.h b/components/esp_rom/esp32c6/include/esp32c6/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/aes.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/aes.h diff --git a/components/esp_rom/include/esp32c6/rom/bigint.h b/components/esp_rom/esp32c6/include/esp32c6/rom/bigint.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/bigint.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/bigint.h diff --git a/components/esp_rom/include/esp32c6/rom/cache.h b/components/esp_rom/esp32c6/include/esp32c6/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32c6/rom/cache.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/cache.h index dfa657e865b..7e0eaa67e76 100644 --- a/components/esp_rom/include/esp32c6/rom/cache.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/cache.h @@ -561,7 +561,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32c6/rom/crc.h b/components/esp_rom/esp32c6/include/esp32c6/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/crc.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/crc.h diff --git a/components/esp_rom/include/esp32c6/rom/digital_signature.h b/components/esp_rom/esp32c6/include/esp32c6/rom/digital_signature.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/digital_signature.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/digital_signature.h diff --git a/components/esp_rom/include/esp32c6/rom/ecdsa.h b/components/esp_rom/esp32c6/include/esp32c6/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/ecdsa.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32c6/rom/efuse.h b/components/esp_rom/esp32c6/include/esp32c6/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32c6/rom/efuse.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/efuse.h index 6cd9f4b377e..5854c3eb8a8 100644 --- a/components/esp_rom/include/esp32c6/rom/efuse.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/efuse.h @@ -169,7 +169,7 @@ bool ets_efuse_download_modes_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32c6/rom/esp_flash.h b/components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/esp_flash.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32c6/rom/ets_sys.h b/components/esp_rom/esp32c6/include/esp32c6/rom/ets_sys.h similarity index 97% rename from components/esp_rom/include/esp32c6/rom/ets_sys.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/ets_sys.h index 7c04af3a54c..d4b09896505 100644 --- a/components/esp_rom/include/esp32c6/rom/ets_sys.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/ets_sys.h @@ -61,7 +61,7 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ @@ -80,7 +80,7 @@ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callbac * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -135,7 +135,7 @@ uint8_t ets_get_printf_channel(void); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -145,7 +145,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -188,7 +188,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32c6/rom/gpio.h b/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32c6/rom/gpio.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h index b022c438baa..6ac6dc21daf 100644 --- a/components/esp_rom/include/esp32c6/rom/gpio.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/gpio.h @@ -57,7 +57,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32c6/rom/hmac.h b/components/esp_rom/esp32c6/include/esp32c6/rom/hmac.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/hmac.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/hmac.h diff --git a/components/esp_rom/include/esp32c6/rom/libc_stubs.h b/components/esp_rom/esp32c6/include/esp32c6/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/libc_stubs.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32c6/rom/lldesc.h b/components/esp_rom/esp32c6/include/esp32c6/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/lldesc.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/lldesc.h diff --git a/components/esp_rom/include/esp32c6/rom/md5_hash.h b/components/esp_rom/esp32c6/include/esp32c6/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/md5_hash.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32c6/rom/rom_layout.h b/components/esp_rom/esp32c6/include/esp32c6/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/rom_layout.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32c6/rom/rsa_pss.h b/components/esp_rom/esp32c6/include/esp32c6/rom/rsa_pss.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/rsa_pss.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/rsa_pss.h diff --git a/components/esp_rom/include/esp32c6/rom/rtc.h b/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/rtc.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h diff --git a/components/esp_rom/include/esp32c6/rom/secure_boot.h b/components/esp_rom/esp32c6/include/esp32c6/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/secure_boot.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32c6/rom/sha.h b/components/esp_rom/esp32c6/include/esp32c6/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32c6/rom/sha.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/sha.h diff --git a/components/esp_rom/include/esp32h2/rom/spi_flash.h b/components/esp_rom/esp32c6/include/esp32c6/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32h2/rom/spi_flash.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/spi_flash.h index 2d782dee4f3..70816780e67 100644 --- a/components/esp_rom/include/esp32h2/rom/spi_flash.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/spi_flash.h @@ -421,7 +421,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32c6/rom/tjpgd.h b/components/esp_rom/esp32c6/include/esp32c6/rom/tjpgd.h similarity index 94% rename from components/esp_rom/include/esp32c6/rom/tjpgd.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/tjpgd.h index 3050f865c91..6a4d645b117 100644 --- a/components/esp_rom/include/esp32c6/rom/tjpgd.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/tjpgd.h @@ -76,7 +76,7 @@ struct JDEC { BYTE msx, msy; /* MCU size in unit of block (width, height) */ BYTE qtid[3]; /* Quantization table ID of each component */ SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ + WORD nrst; /* Restart interval */ UINT width, height; /* Size of the input image (pixel) */ BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */ @@ -85,9 +85,9 @@ struct JDEC { void *workbuf; /* Working buffer for IDCT and RGB output */ BYTE *mcubuf; /* Working buffer for the MCU */ void *pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT sz_pool; /* Size of memory pool (bytes available) */ UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */ - void *device; /* Pointer to I/O device identifiler for the session */ + void *device; /* Pointer to I/O device identifier for the session */ }; diff --git a/components/esp_rom/include/esp32h2/rom/uart.h b/components/esp_rom/esp32c6/include/esp32c6/rom/uart.h similarity index 97% rename from components/esp_rom/include/esp32h2/rom/uart.h rename to components/esp_rom/esp32c6/include/esp32c6/rom/uart.h index 9045c42f6f6..c21c0914403 100644 --- a/components/esp_rom/include/esp32h2/rom/uart.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -263,14 +263,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/components/esp_rom/esp32c61/Kconfig.soc_caps.in b/components/esp_rom/esp32c61/Kconfig.soc_caps.in index 67076708db0..e5e00f60471 100644 --- a/components/esp_rom/esp32c61/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c61/Kconfig.soc_caps.in @@ -51,6 +51,10 @@ config ESP_ROM_TLSF_CHECK_PATCH bool default y +config ESP_ROM_MULTI_HEAP_WALK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c61/esp_rom_caps.h b/components/esp_rom/esp32c61/esp_rom_caps.h index aea1da0391b..ba643612709 100644 --- a/components/esp_rom/esp32c61/esp_rom_caps.h +++ b/components/esp_rom/esp32c61/esp_rom_caps.h @@ -18,6 +18,7 @@ #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library #define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() +#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver // TODO: [ESP32C61] IDF-9276, still should be true, temp commented diff --git a/components/esp_rom/include/esp32c61/rom/bigint.h b/components/esp_rom/esp32c61/include/esp32c61/rom/bigint.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/bigint.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/bigint.h diff --git a/components/esp_rom/include/esp32c61/rom/cache.h b/components/esp_rom/esp32c61/include/esp32c61/rom/cache.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/cache.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/cache.h diff --git a/components/esp_rom/include/esp32c61/rom/crc.h b/components/esp_rom/esp32c61/include/esp32c61/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/crc.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/crc.h diff --git a/components/esp_rom/include/esp32c61/rom/ecdsa.h b/components/esp_rom/esp32c61/include/esp32c61/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/ecdsa.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32c61/rom/efuse.h b/components/esp_rom/esp32c61/include/esp32c61/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32c61/rom/efuse.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/efuse.h index 2c957125798..be4bdf9c797 100644 --- a/components/esp_rom/include/esp32c61/rom/efuse.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/efuse.h @@ -169,7 +169,7 @@ bool ets_efuse_download_modes_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32c61/rom/esp_flash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/esp_flash.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32c61/rom/ets_sys.h b/components/esp_rom/esp32c61/include/esp32c61/rom/ets_sys.h similarity index 97% rename from components/esp_rom/include/esp32c61/rom/ets_sys.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/ets_sys.h index 516a694fcdb..7160a95d80a 100644 --- a/components/esp_rom/include/esp32c61/rom/ets_sys.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/ets_sys.h @@ -61,7 +61,7 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ @@ -80,7 +80,7 @@ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callbac * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -135,7 +135,7 @@ uint8_t ets_get_printf_channel(void); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -145,7 +145,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -188,7 +188,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32c61/rom/gpio.h b/components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/gpio.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/gpio.h diff --git a/components/esp_rom/include/esp32c61/rom/libc_stubs.h b/components/esp_rom/esp32c61/include/esp32c61/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/libc_stubs.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32c61/rom/lldesc.h b/components/esp_rom/esp32c61/include/esp32c61/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/lldesc.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/lldesc.h diff --git a/components/esp_rom/include/esp32c61/rom/md5_hash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/md5_hash.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32c61/rom/opi_flash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h similarity index 98% rename from components/esp_rom/include/esp32c61/rom/opi_flash.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h index e3412d19621..8a5236801c8 100644 --- a/components/esp_rom/include/esp32c61/rom/opi_flash.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/opi_flash.h @@ -55,8 +55,8 @@ typedef struct { uint32_t addrBitLen; /*!< Address byte length*/ uint32_t *txData; /*!< Point to send data buffer*/ uint32_t txDataBitLen; /*!< Send data byte length.*/ - uint32_t *rxData; /*!< Point to recevie data buffer*/ - uint32_t rxDataBitLen; /*!< Recevie Data byte length.*/ + uint32_t *rxData; /*!< Point to receive data buffer*/ + uint32_t rxDataBitLen; /*!< Receive Data byte length.*/ uint32_t dummyBitLen; } esp_rom_spi_cmd_t; diff --git a/components/esp_rom/include/esp32c61/rom/rom_layout.h b/components/esp_rom/esp32c61/include/esp32c61/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/rom_layout.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32c61/rom/rtc.h b/components/esp_rom/esp32c61/include/esp32c61/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/rtc.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/rtc.h diff --git a/components/esp_rom/include/esp32c61/rom/secure_boot.h b/components/esp_rom/esp32c61/include/esp32c61/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/secure_boot.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32c61/rom/sha.h b/components/esp_rom/esp32c61/include/esp32c61/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32c61/rom/sha.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/sha.h diff --git a/components/esp_rom/include/esp32c61/rom/spi_flash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32c61/rom/spi_flash.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/spi_flash.h index b3bcc374092..0b6e0afb6d4 100644 --- a/components/esp_rom/include/esp32c61/rom/spi_flash.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/spi_flash.h @@ -421,7 +421,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32c61/rom/tjpgd.h b/components/esp_rom/esp32c61/include/esp32c61/rom/tjpgd.h similarity index 94% rename from components/esp_rom/include/esp32c61/rom/tjpgd.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/tjpgd.h index b993c2f5324..b494e70bbe9 100644 --- a/components/esp_rom/include/esp32c61/rom/tjpgd.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/tjpgd.h @@ -76,7 +76,7 @@ struct JDEC { BYTE msx, msy; /* MCU size in unit of block (width, height) */ BYTE qtid[3]; /* Quantization table ID of each component */ SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ + WORD nrst; /* Restart interval */ UINT width, height; /* Size of the input image (pixel) */ BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */ @@ -85,9 +85,9 @@ struct JDEC { void *workbuf; /* Working buffer for IDCT and RGB output */ BYTE *mcubuf; /* Working buffer for the MCU */ void *pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT sz_pool; /* Size of memory pool (bytes available) */ UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */ - void *device; /* Pointer to I/O device identifiler for the session */ + void *device; /* Pointer to I/O device identifier for the session */ }; diff --git a/components/esp_rom/include/esp32c61/rom/uart.h b/components/esp_rom/esp32c61/include/esp32c61/rom/uart.h similarity index 97% rename from components/esp_rom/include/esp32c61/rom/uart.h rename to components/esp_rom/esp32c61/include/esp32c61/rom/uart.h index 57e3cf6618a..dba76699eae 100644 --- a/components/esp_rom/include/esp32c61/rom/uart.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -263,14 +263,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/components/esp_rom/include/esp32h2/rom/aes.h b/components/esp_rom/esp32h2/include/esp32h2/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/aes.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/aes.h diff --git a/components/esp_rom/include/esp32h2/rom/bigint.h b/components/esp_rom/esp32h2/include/esp32h2/rom/bigint.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/bigint.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/bigint.h diff --git a/components/esp_rom/include/esp32h2/rom/cache.h b/components/esp_rom/esp32h2/include/esp32h2/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32h2/rom/cache.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/cache.h index 37a8201b17e..4559177976b 100644 --- a/components/esp_rom/include/esp32h2/rom/cache.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/cache.h @@ -564,7 +564,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32h2/rom/crc.h b/components/esp_rom/esp32h2/include/esp32h2/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/crc.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/crc.h diff --git a/components/esp_rom/include/esp32h2/rom/digital_signature.h b/components/esp_rom/esp32h2/include/esp32h2/rom/digital_signature.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/digital_signature.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/digital_signature.h diff --git a/components/esp_rom/include/esp32h2/rom/ecdsa.h b/components/esp_rom/esp32h2/include/esp32h2/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/ecdsa.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32h2/rom/efuse.h b/components/esp_rom/esp32h2/include/esp32h2/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32h2/rom/efuse.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/efuse.h index dc612dff4b8..fbd1721211b 100644 --- a/components/esp_rom/include/esp32h2/rom/efuse.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/efuse.h @@ -170,7 +170,7 @@ bool ets_efuse_download_modes_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32h2/rom/esp_flash.h b/components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/esp_flash.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32h2/rom/ets_sys.h b/components/esp_rom/esp32h2/include/esp32h2/rom/ets_sys.h similarity index 97% rename from components/esp_rom/include/esp32h2/rom/ets_sys.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/ets_sys.h index b9247bc3bdf..0b19741d5d0 100644 --- a/components/esp_rom/include/esp32h2/rom/ets_sys.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/ets_sys.h @@ -61,7 +61,7 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ @@ -80,7 +80,7 @@ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callbac * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -135,7 +135,7 @@ uint8_t ets_get_printf_channel(void); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -145,7 +145,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -188,7 +188,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32h2/rom/gpio.h b/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32h2/rom/gpio.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h index 67fb476f5ca..5829765c607 100644 --- a/components/esp_rom/include/esp32h2/rom/gpio.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/gpio.h @@ -57,7 +57,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32h2/rom/hmac.h b/components/esp_rom/esp32h2/include/esp32h2/rom/hmac.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/hmac.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/hmac.h diff --git a/components/esp_rom/include/esp32h2/rom/libc_stubs.h b/components/esp_rom/esp32h2/include/esp32h2/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/libc_stubs.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32h2/rom/lldesc.h b/components/esp_rom/esp32h2/include/esp32h2/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/lldesc.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/lldesc.h diff --git a/components/esp_rom/include/esp32h2/rom/md5_hash.h b/components/esp_rom/esp32h2/include/esp32h2/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/md5_hash.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32h2/rom/rom_layout.h b/components/esp_rom/esp32h2/include/esp32h2/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/rom_layout.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32h2/rom/rsa_pss.h b/components/esp_rom/esp32h2/include/esp32h2/rom/rsa_pss.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/rsa_pss.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/rsa_pss.h diff --git a/components/esp_rom/include/esp32h2/rom/rtc.h b/components/esp_rom/esp32h2/include/esp32h2/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/rtc.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/rtc.h diff --git a/components/esp_rom/include/esp32h2/rom/secure_boot.h b/components/esp_rom/esp32h2/include/esp32h2/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/secure_boot.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32h2/rom/sha.h b/components/esp_rom/esp32h2/include/esp32h2/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32h2/rom/sha.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/sha.h diff --git a/components/esp_rom/include/esp32c6/rom/spi_flash.h b/components/esp_rom/esp32h2/include/esp32h2/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32c6/rom/spi_flash.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/spi_flash.h index 2d782dee4f3..70816780e67 100644 --- a/components/esp_rom/include/esp32c6/rom/spi_flash.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/spi_flash.h @@ -421,7 +421,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32c6/rom/uart.h b/components/esp_rom/esp32h2/include/esp32h2/rom/uart.h similarity index 97% rename from components/esp_rom/include/esp32c6/rom/uart.h rename to components/esp_rom/esp32h2/include/esp32h2/rom/uart.h index 9045c42f6f6..c21c0914403 100644 --- a/components/esp_rom/include/esp32c6/rom/uart.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -263,14 +263,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/components/esp_rom/include/esp32p4/rom/aes.h b/components/esp_rom/esp32p4/include/esp32p4/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/aes.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/aes.h diff --git a/components/esp_rom/include/esp32p4/rom/bigint.h b/components/esp_rom/esp32p4/include/esp32p4/rom/bigint.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/bigint.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/bigint.h diff --git a/components/esp_rom/include/esp32p4/rom/cache.h b/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32p4/rom/cache.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/cache.h index 95f4a4db05e..49b084b3ab9 100644 --- a/components/esp_rom/include/esp32p4/rom/cache.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h @@ -507,7 +507,7 @@ void ROM_Direct_Boot_Cache_Init(void); * * @param None * - * @return 0 if mmu map is sucessfully, others if not. + * @return 0 if mmu map is successfully, others if not. */ int ROM_Direct_Boot_MMU_Init(void); @@ -1517,7 +1517,7 @@ void Cache_Freeze_L2_Cache_Disable(void); void Cache_Travel_Tag_Memory(struct cache_mode *mode, uint32_t filter_addr, void (*process)(struct tag_group_info *, int res[]), int res[]); /** - * @brief Travel tag memory to run a call back function using 2rd tag api. + * @brief Travel tag memory to run a call back function using 2nd tag api. * ICache and DCache are suspend when doing this. * The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses. * Please do not call this function in your SDK application. @@ -1539,7 +1539,7 @@ void Cache_Travel_Tag_Memory2(struct cache_mode *mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32p4/rom/crc.h b/components/esp_rom/esp32p4/include/esp32p4/rom/crc.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/crc.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/crc.h diff --git a/components/esp_rom/include/esp32p4/rom/digital_signature.h b/components/esp_rom/esp32p4/include/esp32p4/rom/digital_signature.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/digital_signature.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/digital_signature.h diff --git a/components/esp_rom/include/esp32p4/rom/ecdsa.h b/components/esp_rom/esp32p4/include/esp32p4/rom/ecdsa.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/ecdsa.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/ecdsa.h diff --git a/components/esp_rom/include/esp32p4/rom/efuse.h b/components/esp_rom/esp32p4/include/esp32p4/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32p4/rom/efuse.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/efuse.h index 60b7726d115..60d8498dd01 100644 --- a/components/esp_rom/include/esp32p4/rom/efuse.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/efuse.h @@ -58,7 +58,7 @@ typedef enum { } ets_efuse_block_t; /** - * @brief set timing accroding the apb clock, so no read error or write error happens. + * @brief set timing according the apb clock, so no read error or write error happens. * * @param clock: apb clock in HZ, only accept 5M(in FPGA), 10M(in FPGA), 20M, 40M, 80M. * @@ -226,7 +226,7 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO8 is low when digital reset. * 2 for uart print when GPIO8 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32p4/rom/esp_flash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/esp_flash.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h diff --git a/components/esp_rom/include/esp32p4/rom/ets_sys.h b/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h similarity index 96% rename from components/esp_rom/include/esp32p4/rom/ets_sys.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h index 5ee1383cb16..95d8b092fcc 100644 --- a/components/esp_rom/include/esp32p4/rom/ets_sys.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h @@ -58,11 +58,11 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ /** - * @brief Start the Espressif Task Scheduler, which is an infinit loop. Please do not add code after it. + * @brief Start the Espressif Task Scheduler, which is an infinite loop. Please do not add code after it. * * @param none * @@ -82,9 +82,9 @@ void ets_run(void); void ets_set_idle_cb(ets_idle_cb_t func, void *arg); /** - * @brief Init a task with processer, priority, queue to receive Event, queue length. + * @brief Init a task with processor, priority, queue to receive Event, queue length. * - * @param ETSTask task : The task processer. + * @param ETSTask task : The task processor. * * @param uint8_t prio : Task priority, 0-31, bigger num with high priority, one priority with one task. * @@ -122,7 +122,7 @@ ETS_STATUS ets_post(uint8_t prio, ETSSignal sig, ETSParam par); * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -179,7 +179,7 @@ uint8_t ets_get_printf_channel(void); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -189,7 +189,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -232,7 +232,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32p4/rom/gpio.h b/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32p4/rom/gpio.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h index 214eaff048c..e59383319bc 100644 --- a/components/esp_rom/include/esp32p4/rom/gpio.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/gpio.h @@ -78,7 +78,7 @@ void gpio_init(void); * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ @@ -95,7 +95,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32p4/rom/hmac.h b/components/esp_rom/esp32p4/include/esp32p4/rom/hmac.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/hmac.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/hmac.h diff --git a/components/esp_rom/include/esp32p4/rom/key_mgr.h b/components/esp_rom/esp32p4/include/esp32p4/rom/key_mgr.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/key_mgr.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/key_mgr.h diff --git a/components/esp_rom/include/esp32p4/rom/km.h b/components/esp_rom/esp32p4/include/esp32p4/rom/km.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/km.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/km.h diff --git a/components/esp_rom/include/esp32p4/rom/libc_stubs.h b/components/esp_rom/esp32p4/include/esp32p4/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/libc_stubs.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32p4/rom/lldesc.h b/components/esp_rom/esp32p4/include/esp32p4/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/lldesc.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/lldesc.h diff --git a/components/esp_rom/include/esp32p4/rom/md5_hash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/md5_hash.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32p4/rom/opi_flash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h similarity index 98% rename from components/esp_rom/include/esp32p4/rom/opi_flash.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h index 9eff17f2ef1..3184c98e3a3 100644 --- a/components/esp_rom/include/esp32p4/rom/opi_flash.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/opi_flash.h @@ -57,8 +57,8 @@ typedef struct { uint32_t addrBitLen; /*!< Address byte length*/ uint32_t *txData; /*!< Point to send data buffer*/ uint32_t txDataBitLen; /*!< Send data byte length.*/ - uint32_t *rxData; /*!< Point to recevie data buffer*/ - uint32_t rxDataBitLen; /*!< Recevie Data byte length.*/ + uint32_t *rxData; /*!< Point to receive data buffer*/ + uint32_t rxDataBitLen; /*!< Receive Data byte length.*/ uint32_t dummyBitLen; } esp_rom_spi_cmd_t; diff --git a/components/esp_rom/include/esp32p4/rom/rom_layout.h b/components/esp_rom/esp32p4/include/esp32p4/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/rom_layout.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32p4/rom/rsa_pss.h b/components/esp_rom/esp32p4/include/esp32p4/rom/rsa_pss.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/rsa_pss.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/rsa_pss.h diff --git a/components/esp_rom/include/esp32p4/rom/rtc.h b/components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/rtc.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h diff --git a/components/esp_rom/include/esp32p4/rom/secure_boot.h b/components/esp_rom/esp32p4/include/esp32p4/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/secure_boot.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32p4/rom/sha.h b/components/esp_rom/esp32p4/include/esp32p4/rom/sha.h similarity index 100% rename from components/esp_rom/include/esp32p4/rom/sha.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/sha.h diff --git a/components/esp_rom/include/esp32p4/rom/spi_flash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32p4/rom/spi_flash.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/spi_flash.h index 761fc46bc7f..72e5f90cfdf 100644 --- a/components/esp_rom/include/esp32p4/rom/spi_flash.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/spi_flash.h @@ -459,7 +459,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32p4/rom/uart.h b/components/esp_rom/esp32p4/include/esp32p4/rom/uart.h similarity index 98% rename from components/esp_rom/include/esp32p4/rom/uart.h rename to components/esp_rom/esp32p4/include/esp32p4/rom/uart.h index 60258dceb68..b3a399356cd 100644 --- a/components/esp_rom/include/esp32p4/rom/uart.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -286,14 +286,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/components/esp_rom/include/esp32s2/rom/aes.h b/components/esp_rom/esp32s2/include/esp32s2/rom/aes.h similarity index 59% rename from components/esp_rom/include/esp32s2/rom/aes.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/aes.h index 9350e2511ea..50497c252ec 100644 --- a/components/esp_rom/include/esp32s2/rom/aes.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/aes.h @@ -5,19 +5,11 @@ use the wrapper functions in hwcrypto/aes.h instead. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s2/rom/bigint.h b/components/esp_rom/esp32s2/include/esp32s2/rom/bigint.h similarity index 59% rename from components/esp_rom/include/esp32s2/rom/bigint.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/bigint.h index eee19d46bbf..418a41de365 100644 --- a/components/esp_rom/include/esp32s2/rom/bigint.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/bigint.h @@ -5,19 +5,11 @@ use the wrapper functions in hwcrypto/mpi.h instead. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_BIGINT_H_ #define _ROM_BIGINT_H_ diff --git a/components/esp_rom/include/esp32s2/rom/cache.h b/components/esp_rom/esp32s2/include/esp32s2/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32s2/rom/cache.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/cache.h index cdfa143a7da..7ee63be904b 100644 --- a/components/esp_rom/include/esp32s2/rom/cache.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/cache.h @@ -90,7 +90,7 @@ struct tag_item { uint32_t fifo_cnt:3; /*!< fifo cnt, 0 ~ 3 for 4 ways cache, 0 ~ 7 for 8 ways cache */ uint32_t lock:1; /*!< the cache line is locked or not */ uint32_t attr:3; /*!< the attribute of the external memory physical address */ - uint32_t access:1; /*!< software accessable, used by hardware */ + uint32_t access:1; /*!< software accessible, used by hardware */ uint32_t reserved:8; }; @@ -884,7 +884,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32s2/rom/crc.h b/components/esp_rom/esp32s2/include/esp32s2/rom/crc.h similarity index 72% rename from components/esp_rom/include/esp32s2/rom/crc.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/crc.h index 0d139795761..344a43f1b52 100644 --- a/components/esp_rom/include/esp32s2/rom/crc.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/crc.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef ROM_CRC_H #define ROM_CRC_H diff --git a/components/esp_rom/include/esp32s2/rom/digital_signature.h b/components/esp_rom/esp32s2/include/esp32s2/rom/digital_signature.h similarity index 89% rename from components/esp_rom/include/esp32s2/rom/digital_signature.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/digital_signature.h index 9f23a5d6b86..8590b9c8be5 100644 --- a/components/esp_rom/include/esp32s2/rom/digital_signature.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/digital_signature.h @@ -1,19 +1,11 @@ /* ROM functions for hardware Digital Signature peripheral verification */ -// Copyright 2019 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. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s2/rom/efuse.h b/components/esp_rom/esp32s2/include/esp32s2/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32s2/rom/efuse.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/efuse.h index 6f4e8812b36..290a5567ba6 100644 --- a/components/esp_rom/include/esp32s2/rom/efuse.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/efuse.h @@ -56,7 +56,7 @@ typedef enum { } ets_efuse_block_t; /** - * @brief set timing accroding the apb clock, so no read error or write error happens. + * @brief set timing according the apb clock, so no read error or write error happens. * * @param clock: apb clock in HZ, only accept 20M, 40M, 80M. * @@ -224,7 +224,7 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO46 is low when digital reset. * 2 for uart print when GPIO46 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32s2/rom/ets_sys.h b/components/esp_rom/esp32s2/include/esp32s2/rom/ets_sys.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/ets_sys.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/ets_sys.h diff --git a/components/esp_rom/include/esp32s2/rom/gpio.h b/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h similarity index 97% rename from components/esp_rom/include/esp32s2/rom/gpio.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h index 991b20352d8..84e0af1adbd 100644 --- a/components/esp_rom/include/esp32s2/rom/gpio.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/gpio.h @@ -62,7 +62,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ @@ -79,7 +79,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32c3/rom/hmac.h b/components/esp_rom/esp32s2/include/esp32s2/rom/hmac.h similarity index 71% rename from components/esp_rom/include/esp32c3/rom/hmac.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/hmac.h index 223fe884a3d..09e8b1effda 100644 --- a/components/esp_rom/include/esp32c3/rom/hmac.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/hmac.h @@ -1,16 +1,8 @@ -// Copyright 2020 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. +/* + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_HMAC_H_ #define _ROM_HMAC_H_ diff --git a/components/esp_rom/include/esp32s2/rom/libc_stubs.h b/components/esp_rom/esp32s2/include/esp32s2/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/libc_stubs.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32s2/rom/lldesc.h b/components/esp_rom/esp32s2/include/esp32s2/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/lldesc.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/lldesc.h diff --git a/components/esp_rom/include/esp32s2/rom/md5_hash.h b/components/esp_rom/esp32s2/include/esp32s2/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/md5_hash.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32s2/rom/opi_flash.h b/components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h similarity index 98% rename from components/esp_rom/include/esp32s2/rom/opi_flash.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h index c7e789b0201..371db2185db 100644 --- a/components/esp_rom/include/esp32s2/rom/opi_flash.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h @@ -21,8 +21,8 @@ typedef struct { uint32_t addrBitLen; /*!< Address byte length*/ uint32_t *txData; /*!< Point to send data buffer*/ uint32_t txDataBitLen; /*!< Send data byte length.*/ - uint32_t *rxData; /*!< Point to recevie data buffer*/ - uint32_t rxDataBitLen; /*!< Recevie Data byte length.*/ + uint32_t *rxData; /*!< Point to receive data buffer*/ + uint32_t rxDataBitLen; /*!< Receive Data byte length.*/ uint32_t dummyBitLen; } esp_rom_spi_cmd_t; diff --git a/components/esp_rom/include/esp32s2/rom/rsa_pss.h b/components/esp_rom/esp32s2/include/esp32s2/rom/rsa_pss.h similarity index 53% rename from components/esp_rom/include/esp32s2/rom/rsa_pss.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/rsa_pss.h index bfbaeb6a41d..5ec11a0e241 100644 --- a/components/esp_rom/include/esp32s2/rom/rsa_pss.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/rsa_pss.h @@ -1,22 +1,15 @@ -// Copyright 2015-2018 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_RSA_PSS_H_ #define _ROM_RSA_PSS_H_ #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/components/esp_rom/include/esp32s2/rom/rtc.h b/components/esp_rom/esp32s2/include/esp32s2/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/rtc.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/rtc.h diff --git a/components/esp_rom/include/esp32s2/rom/secure_boot.h b/components/esp_rom/esp32s2/include/esp32s2/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/secure_boot.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32s2/rom/sha.h b/components/esp_rom/esp32s2/include/esp32s2/rom/sha.h similarity index 70% rename from components/esp_rom/include/esp32s2/rom/sha.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/sha.h index f04e9aec507..ad3e4dd650a 100644 --- a/components/esp_rom/include/esp32s2/rom/sha.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/sha.h @@ -6,19 +6,11 @@ esp_sha_lock_memory_block() functions in hwcrypto/sha.h to ensure exclusive access. */ -// Copyright 2015-2016 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_SHA_H_ #define _ROM_SHA_H_ diff --git a/components/esp_rom/include/esp32s2/rom/spi_flash.h b/components/esp_rom/esp32s2/include/esp32s2/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32s2/rom/spi_flash.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/spi_flash.h index b496bc1b991..6711e81aa09 100644 --- a/components/esp_rom/include/esp32s2/rom/spi_flash.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/spi_flash.h @@ -416,7 +416,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32s2/rom/uart.h b/components/esp_rom/esp32s2/include/esp32s2/rom/uart.h similarity index 98% rename from components/esp_rom/include/esp32s2/rom/uart.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/uart.h index 491d2c28fbe..a3ebc5f2350 100644 --- a/components/esp_rom/include/esp32s2/rom/uart.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/uart.h @@ -28,7 +28,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -301,14 +301,14 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); /** - * @brief Process uart recevied information in the interrupt handler. + * @brief Process uart received information in the interrupt handler. * Please do not call this function in SDK. * * @param void *para : the message receive buffer. diff --git a/components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/cdc_acm.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/cdc_acm.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/cpio.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/cpio.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/cpio.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/cpio.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_cdc.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_cdc.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_common.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_common.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_common.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_common.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_dc.h similarity index 99% rename from components/esp_rom/include/esp32s2/rom/usb/usb_dc.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_dc.h index 5587cc22ba8..0d25f50fc1b 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_dc.h @@ -365,7 +365,7 @@ int usb_dc_ep_read_continue(uint8_t ep); * @param[in] ep Endpoint address corresponding to the one * listed in the device configuration table * - * @return enpoint max packet size (mps) + * @return endpoint max packet size (mps) */ int usb_dc_ep_mps(uint8_t ep); @@ -384,7 +384,7 @@ void usb_dc_check_poll_for_interrupts(void); * * This takes the USB peripheral offline in such a way that it seems 'just busy' to the * host. This way, the chip can reboot (e.g. into bootloader mode) and pick up the USB - * configuration again, without the conenction to the host being interrupted. + * configuration again, without the connection to the host being interrupted. * * @note Actual persistence is depending on USBDC_PERSIST_ENA being set in flags, as this * is also used to e.g. reboot into DFU mode. diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_descriptor.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_descriptor.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_device.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_device.h similarity index 99% rename from components/esp_rom/include/esp32s3/rom/usb/usb_device.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_device.h index 87dbcda15b2..bd9739fa523 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_device.h +++ b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_device.h @@ -248,7 +248,7 @@ int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len, * @brief set STALL condition on the specified endpoint * * This function is called by USB device class handler code to set stall - * conditionin on endpoint. + * condition on endpoint. * * @param[in] ep Endpoint address corresponding to the one listed in * the device configuration table @@ -262,7 +262,7 @@ int usb_ep_set_stall(uint8_t ep); * @brief clears STALL condition on the specified endpoint * * This function is called by USB device class handler code to clear stall - * conditionin on endpoint. + * condition on endpoint. * * @param[in] ep Endpoint address corresponding to the one listed in * the device configuration table diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_dfu.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_dfu.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_os_glue.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_os_glue.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_persist.h b/components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_persist.h similarity index 100% rename from components/esp_rom/include/esp32s2/rom/usb/usb_persist.h rename to components/esp_rom/esp32s2/include/esp32s2/rom/usb/usb_persist.h diff --git a/components/esp_rom/include/esp32s3/rom/aes.h b/components/esp_rom/esp32s3/include/esp32s3/rom/aes.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/aes.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/aes.h diff --git a/components/esp_rom/include/esp32s3/rom/apb_backup_dma.h b/components/esp_rom/esp32s3/include/esp32s3/rom/apb_backup_dma.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/apb_backup_dma.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/apb_backup_dma.h diff --git a/components/esp_rom/include/esp32s3/rom/bigint.h b/components/esp_rom/esp32s3/include/esp32s3/rom/bigint.h similarity index 51% rename from components/esp_rom/include/esp32s3/rom/bigint.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/bigint.h index 2ab022d87d2..49d4a2a9310 100644 --- a/components/esp_rom/include/esp32s3/rom/bigint.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/bigint.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/cache.h b/components/esp_rom/esp32s3/include/esp32s3/rom/cache.h similarity index 99% rename from components/esp_rom/include/esp32s3/rom/cache.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/cache.h index e0be832c568..1a90324a05d 100644 --- a/components/esp_rom/include/esp32s3/rom/cache.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/cache.h @@ -160,7 +160,7 @@ struct tag_group_info { uint32_t vaddr_offset; /*!< virtual address offset of the cache ways */ uint32_t tag_addr[MAX_CACHE_WAYS]; /*!< tag memory address, only [0~mode.ways-1] is valid to use */ uint32_t cache_memory_offset[MAX_CACHE_WAYS]; /*!< cache memory address, only [0~mode.ways-1] is valid to use */ - uint8_t use_legacy; /*!< 1 for using legacy tag api, 0 for using 2rd tag api */ + uint8_t use_legacy; /*!< 1 for using legacy tag api, 0 for using 2nd tag api */ }; struct lock_config { @@ -1096,7 +1096,7 @@ void Cache_Travel_Tag_Memory2(struct cache_mode * mode, uint32_t filter_addr, vo * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32s3/rom/crc.h b/components/esp_rom/esp32s3/include/esp32s3/rom/crc.h similarity index 81% rename from components/esp_rom/include/esp32s3/rom/crc.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/crc.h index e47a2ff580a..431b8d6efb9 100644 --- a/components/esp_rom/include/esp32s3/rom/crc.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/crc.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/digital_signature.h b/components/esp_rom/esp32s3/include/esp32s3/rom/digital_signature.h similarity index 88% rename from components/esp_rom/include/esp32s3/rom/digital_signature.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/digital_signature.h index 36e71e7c4f3..e05b0a3712e 100644 --- a/components/esp_rom/include/esp32s3/rom/digital_signature.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/digital_signature.h @@ -1,16 +1,8 @@ -// Copyright 2019-2020 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. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/efuse.h b/components/esp_rom/esp32s3/include/esp32s3/rom/efuse.h similarity index 99% rename from components/esp_rom/include/esp32s3/rom/efuse.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/efuse.h index c34ca57de10..a2aac78c9d2 100644 --- a/components/esp_rom/include/esp32s3/rom/efuse.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/efuse.h @@ -56,7 +56,7 @@ typedef enum { } ets_efuse_block_t; /** - * @brief set timing accroding the apb clock, so no read error or write error happens. + * @brief set timing according the apb clock, so no read error or write error happens. * * @param clock: apb clock in HZ, only accept 5M(in FPGA), 10M(in FPGA), 20M, 40M, 80M. * @@ -209,7 +209,7 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); * - 0 for uart force print. * - 1 for uart print when GPIO46 is low when digital reset. * 2 for uart print when GPIO46 is high when digital reset. - * 3 for uart force slient + * 3 for uart force silent */ uint32_t ets_efuse_get_uart_print_control(void); diff --git a/components/esp_rom/include/esp32s3/rom/ets_sys.h b/components/esp_rom/esp32s3/include/esp32s3/rom/ets_sys.h similarity index 98% rename from components/esp_rom/include/esp32s3/rom/ets_sys.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/ets_sys.h index 83c93b2eb6a..7bc91572f2a 100644 --- a/components/esp_rom/include/esp32s3/rom/ets_sys.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/ets_sys.h @@ -61,7 +61,7 @@ struct ETSEventTag { ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ }; -typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processor*/ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ @@ -80,7 +80,7 @@ typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callbac * @{ */ -extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ +extern const char *const exc_cause_table[40]; ///**< exception cause that defined by the core.*/ /** * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. @@ -145,7 +145,7 @@ uint8_t ets_get_printf_channel(void); void ets_write_char_uart(char c); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. * * @param void (*)(char) p: Output function to install. @@ -155,7 +155,7 @@ void ets_write_char_uart(char c); void ets_install_putc1(void (*p)(char c)); /** - * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need output. * To install putc2, which is defaulted installed as NULL. * * @param void (*)(char) p: Output function to install. @@ -198,7 +198,7 @@ typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ typedef struct _ETSTIMER_ { struct _ETSTIMER_ *timer_next; /**< timer linker*/ - uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_expire; /**< abstract time when timer expire*/ uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ ETSTimerFunc *timer_func; /**< timer handler*/ void *timer_arg; /**< timer handler argument*/ diff --git a/components/esp_rom/include/esp32s3/rom/gpio.h b/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h similarity index 98% rename from components/esp_rom/include/esp32s3/rom/gpio.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h index 13b9c9a60bb..8958b03578b 100644 --- a/components/esp_rom/include/esp32s3/rom/gpio.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/gpio.h @@ -57,7 +57,7 @@ typedef enum { * * @param uint32_t enable_mask : the gpios that need be changed. * - * @param uint32_t disable_mask : the gpios that need diable output. + * @param uint32_t disable_mask : the gpios that need disable output. * * @return None */ diff --git a/components/esp_rom/include/esp32s3/rom/hmac.h b/components/esp_rom/esp32s3/include/esp32s3/rom/hmac.h similarity index 70% rename from components/esp_rom/include/esp32s3/rom/hmac.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/hmac.h index ac7ddf358ed..2c65b0fc859 100644 --- a/components/esp_rom/include/esp32s3/rom/hmac.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/hmac.h @@ -1,16 +1,8 @@ -// Copyright 2018-2020 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. +/* + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/libc_stubs.h b/components/esp_rom/esp32s3/include/esp32s3/rom/libc_stubs.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/libc_stubs.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/libc_stubs.h diff --git a/components/esp_rom/include/esp32s3/rom/lldesc.h b/components/esp_rom/esp32s3/include/esp32s3/rom/lldesc.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/lldesc.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/lldesc.h diff --git a/components/esp_rom/include/esp32s3/rom/md5_hash.h b/components/esp_rom/esp32s3/include/esp32s3/rom/md5_hash.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/md5_hash.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/md5_hash.h diff --git a/components/esp_rom/include/esp32s3/rom/opi_flash.h b/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h similarity index 98% rename from components/esp_rom/include/esp32s3/rom/opi_flash.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h index 8976e7b53e7..3f5d8405498 100644 --- a/components/esp_rom/include/esp32s3/rom/opi_flash.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h @@ -55,8 +55,8 @@ typedef struct { uint32_t addrBitLen; /*!< Address byte length*/ uint32_t *txData; /*!< Point to send data buffer*/ uint32_t txDataBitLen; /*!< Send data byte length.*/ - uint32_t *rxData; /*!< Point to recevie data buffer*/ - uint32_t rxDataBitLen; /*!< Recevie Data byte length.*/ + uint32_t *rxData; /*!< Point to receive data buffer*/ + uint32_t rxDataBitLen; /*!< Receive Data byte length.*/ uint32_t dummyBitLen; } esp_rom_spi_cmd_t; diff --git a/components/esp_rom/include/esp32s3/rom/rom_layout.h b/components/esp_rom/esp32s3/include/esp32s3/rom/rom_layout.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/rom_layout.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/rom_layout.h diff --git a/components/esp_rom/include/esp32s3/rom/rsa_pss.h b/components/esp_rom/esp32s3/include/esp32s3/rom/rsa_pss.h similarity index 53% rename from components/esp_rom/include/esp32s3/rom/rsa_pss.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/rsa_pss.h index 71ae5892263..23cb0498919 100644 --- a/components/esp_rom/include/esp32s3/rom/rsa_pss.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/rsa_pss.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/rtc.h b/components/esp_rom/esp32s3/include/esp32s3/rom/rtc.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/rtc.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/rtc.h diff --git a/components/esp_rom/include/esp32s3/rom/secure_boot.h b/components/esp_rom/esp32s3/include/esp32s3/rom/secure_boot.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/secure_boot.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/secure_boot.h diff --git a/components/esp_rom/include/esp32s3/rom/sha.h b/components/esp_rom/esp32s3/include/esp32s3/rom/sha.h similarity index 65% rename from components/esp_rom/include/esp32s3/rom/sha.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/sha.h index 4d8fe901955..64a26c69052 100644 --- a/components/esp_rom/include/esp32s3/rom/sha.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/sha.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 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. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include diff --git a/components/esp_rom/include/esp32s3/rom/spi_flash.h b/components/esp_rom/esp32s3/include/esp32s3/rom/spi_flash.h similarity index 99% rename from components/esp_rom/include/esp32s3/rom/spi_flash.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/spi_flash.h index 069fc7dbf3b..519f89eec6f 100644 --- a/components/esp_rom/include/esp32s3/rom/spi_flash.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/spi_flash.h @@ -465,7 +465,7 @@ void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); * * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. - * Values usually read from falsh by rom code, function usually callde by rom code. + * Values usually read from flash by rom code, function usually called by rom code. * if value with bit(3) set, the value is valid, bit[2:0] is the real value. * * @return None diff --git a/components/esp_rom/include/esp32s3/rom/tjpgd.h b/components/esp_rom/esp32s3/include/esp32s3/rom/tjpgd.h similarity index 94% rename from components/esp_rom/include/esp32s3/rom/tjpgd.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/tjpgd.h index 40340dea58c..9d832b42327 100644 --- a/components/esp_rom/include/esp32s3/rom/tjpgd.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/tjpgd.h @@ -71,7 +71,7 @@ struct JDEC { BYTE msx, msy; /* MCU size in unit of block (width, height) */ BYTE qtid[3]; /* Quantization table ID of each component */ SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ + WORD nrst; /* Restart interval */ UINT width, height; /* Size of the input image (pixel) */ BYTE *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ WORD *huffcode[2][2]; /* Huffman code word tables [id][dcac] */ @@ -80,9 +80,9 @@ struct JDEC { void *workbuf; /* Working buffer for IDCT and RGB output */ BYTE *mcubuf; /* Working buffer for the MCU */ void *pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ + UINT sz_pool; /* Size of memory pool (bytes available) */ UINT (*infunc)(JDEC *, BYTE *, UINT); /* Pointer to jpeg stream input function */ - void *device; /* Pointer to I/O device identifiler for the session */ + void *device; /* Pointer to I/O device identifier for the session */ }; /* TJpgDec API functions */ diff --git a/components/esp_rom/include/esp32s3/rom/uart.h b/components/esp_rom/esp32s3/include/esp32s3/rom/uart.h similarity index 98% rename from components/esp_rom/include/esp32s3/rom/uart.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/uart.h index 864563f7883..b427f322628 100644 --- a/components/esp_rom/include/esp32s3/rom/uart.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/uart.h @@ -26,7 +26,7 @@ extern "C" { #define RX_BUFF_SIZE 0x400 #define TX_BUFF_SIZE 100 -//uart int enalbe register ctrl bits +//uart int enable register ctrl bits #define UART_RCV_INTEN BIT0 #define UART_TRX_INTEN BIT1 #define UART_LINE_STATUS_INTEN BIT2 @@ -261,7 +261,7 @@ char uart_rx_one_char_block(void); * * @param uint8_t *pString : the pointer to store the string. * - * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * @param uint8_t MaxStrlen : the max string length, include '\0'. * * @return OK. */ diff --git a/components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/cdc_acm.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/cdc_acm.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/cpio.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/cpio.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/cpio.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/cpio.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_cdc.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_cdc.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_common.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_common.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_common.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_common.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_dc.h similarity index 99% rename from components/esp_rom/include/esp32s3/rom/usb/usb_dc.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_dc.h index 725362fa191..8640c70580c 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_dc.h @@ -365,7 +365,7 @@ int usb_dc_ep_read_continue(uint8_t ep); * @param[in] ep Endpoint address corresponding to the one * listed in the device configuration table * - * @return enpoint max packet size (mps) + * @return endpoint max packet size (mps) */ int usb_dc_ep_mps(uint8_t ep); @@ -384,7 +384,7 @@ void usb_dc_check_poll_for_interrupts(void); * * This takes the USB peripheral offline in such a way that it seems 'just busy' to the * host. This way, the chip can reboot (e.g. into bootloader mode) and pick up the USB - * configuration again, without the conenction to the host being interrupted. + * configuration again, without the connection to the host being interrupted. * * @note Actual persistence is depending on USBDC_PERSIST_ENA being set in flags, as this * is also used to e.g. reboot into DFU mode. diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_descriptor.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_descriptor.h diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_device.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_device.h similarity index 99% rename from components/esp_rom/include/esp32s2/rom/usb/usb_device.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_device.h index 87dbcda15b2..bd9739fa523 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_device.h +++ b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_device.h @@ -248,7 +248,7 @@ int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len, * @brief set STALL condition on the specified endpoint * * This function is called by USB device class handler code to set stall - * conditionin on endpoint. + * condition on endpoint. * * @param[in] ep Endpoint address corresponding to the one listed in * the device configuration table @@ -262,7 +262,7 @@ int usb_ep_set_stall(uint8_t ep); * @brief clears STALL condition on the specified endpoint * * This function is called by USB device class handler code to clear stall - * conditionin on endpoint. + * condition on endpoint. * * @param[in] ep Endpoint address corresponding to the one listed in * the device configuration table diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_dfu.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_dfu.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_os_glue.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_os_glue.h diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_persist.h b/components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_persist.h similarity index 100% rename from components/esp_rom/include/esp32s3/rom/usb/usb_persist.h rename to components/esp_rom/esp32s3/include/esp32s3/rom/usb/usb_persist.h diff --git a/components/esp_rom/include/esp32/rom/miniz.h b/components/esp_rom/include/esp32/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32/rom/tbconsole.h b/components/esp_rom/include/esp32/rom/tbconsole.h deleted file mode 100644 index d6ca069cc75..00000000000 --- a/components/esp_rom/include/esp32/rom/tbconsole.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2016 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. -#ifndef _ROM_TBCONSOLE_H_ -#define _ROM_TBCONSOLE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void start_tb_console(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _ROM_TBCONSOLE_H_ */ diff --git a/components/esp_rom/include/esp32c2/rom/miniz.h b/components/esp_rom/include/esp32c2/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32c2/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c3/rom/miniz.h b/components/esp_rom/include/esp32c3/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32c3/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c5/rom/miniz.h b/components/esp_rom/include/esp32c5/rom/miniz.h deleted file mode 100644 index 357e60a9c12..00000000000 --- a/components/esp_rom/include/esp32c5/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c6/rom/miniz.h b/components/esp_rom/include/esp32c6/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32c6/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c61/rom/miniz.h b/components/esp_rom/include/esp32c61/rom/miniz.h deleted file mode 100644 index 357e60a9c12..00000000000 --- a/components/esp_rom/include/esp32c61/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32s2/rom/miniz.h b/components/esp_rom/include/esp32s2/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32s2/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32s3/rom/miniz.h b/components/esp_rom/include/esp32s3/rom/miniz.h deleted file mode 100644 index f0baecabdce..00000000000 --- a/components/esp_rom/include/esp32s3/rom/miniz.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" -#include "../../miniz.h" diff --git a/components/esp_rom/include/linux/soc/reset_reasons.h b/components/esp_rom/include/linux/soc/reset_reasons.h deleted file mode 100644 index 7cc86ffddfb..00000000000 --- a/components/esp_rom/include/linux/soc/reset_reasons.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 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. - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Dummy to satisfy the requirement for this type on Linux targets. - * Look at other reset_reasons.h files in IDF. - */ -typedef enum { - RESET_REASON_CHIP_POWER_ON = 0x01, // Power on reset -} soc_reset_reason_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_rom/include/linux/rom/efuse.h b/components/esp_rom/linux/include/linux/rom/efuse.h similarity index 100% rename from components/esp_rom/include/linux/rom/efuse.h rename to components/esp_rom/linux/include/linux/rom/efuse.h diff --git a/components/esp_rom/include/linux/rom/ets_sys.h b/components/esp_rom/linux/include/linux/rom/ets_sys.h similarity index 100% rename from components/esp_rom/include/linux/rom/ets_sys.h rename to components/esp_rom/linux/include/linux/rom/ets_sys.h diff --git a/components/esp_rom/linux/include/linux/soc/reset_reasons.h b/components/esp_rom/linux/include/linux/soc/reset_reasons.h new file mode 100644 index 00000000000..f5bd2c1534f --- /dev/null +++ b/components/esp_rom/linux/include/linux/soc/reset_reasons.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Dummy to satisfy the requirement for this type on Linux targets. + * Look at other reset_reasons.h files in IDF. + */ +typedef enum { + RESET_REASON_CHIP_POWER_ON = 0x01, // Power on reset +} soc_reset_reason_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c index f1de5691278..dedebaee470 100644 --- a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c +++ b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c @@ -7,7 +7,6 @@ #include "esp_attr.h" #include "soc/i2c_ana_mst_reg.h" #include "modem/modem_lpcon_reg.h" -#include "soc/pmu_reg.h" #define REGI2C_BIAS_MST_SEL (BIT(8)) #define REGI2C_BBPLL_MST_SEL (BIT(9)) @@ -77,8 +76,6 @@ static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) uint32_t i2c_sel = 0; REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - REG_SET_BIT(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); // TODO: IDF-8642 Move to pmu_init() - REG_SET_BIT(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); // TODO: IDF-8642 Move to pmu_init() /* Before config I2C register, enable corresponding slave. */ switch (block) { diff --git a/components/esp_rom/test_apps/.build-test-rules.yml b/components/esp_rom/test_apps/.build-test-rules.yml index 4f7be937881..7d6745313d3 100644 --- a/components/esp_rom/test_apps/.build-test-rules.yml +++ b/components/esp_rom/test_apps/.build-test-rules.yml @@ -7,9 +7,6 @@ components/esp_rom/test_apps/linux_rom_apis: components/esp_rom/test_apps/rom_impl_components: disable: # For ROM impl build tests, disable them if none of the tested features are supported in the ROM - - if: CONFIG_NAME == "no_rom_impl_components" and IDF_TARGET == "esp32c5" - temporary: true - reason: build failed. track in IDFCI-2204 - if: CONFIG_NAME == "rom_impl_components" and ((ESP_ROM_HAS_HAL_WDT != 1 and ESP_ROM_HAS_HAL_SYSTIMER != 1) and (ESP_ROM_HAS_HEAP_TLSF != 1 and ESP_ROM_HAS_SPI_FLASH != 1)) - if: CONFIG_NAME == "no_rom_impl_components" and ((ESP_ROM_HAS_HAL_WDT != 1 and ESP_ROM_HAS_HAL_SYSTIMER != 1) and (ESP_ROM_HAS_HEAP_TLSF != 1 and ESP_ROM_HAS_SPI_FLASH != 1)) - if: SOC_WDT_SUPPORTED != 1 diff --git a/components/esp_rom/test_apps/rom_impl_components/README.md b/components/esp_rom/test_apps/rom_impl_components/README.md index bf47d80ec64..3a502b1f86f 100644 --- a/components/esp_rom/test_apps/rom_impl_components/README.md +++ b/components/esp_rom/test_apps/rom_impl_components/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py b/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py index eb309c8d195..2bd712f0dd7 100644 --- a/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py +++ b/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/components/esp_system/ld/esp32c5/sections.ld.in b/components/esp_system/ld/esp32c5/sections.ld.in index 54673f7a822..4059d97d362 100644 --- a/components/esp_system/ld/esp32c5/sections.ld.in +++ b/components/esp_system/ld/esp32c5/sections.ld.in @@ -27,6 +27,9 @@ SECTIONS *rtc_wake_stub*.*(.text .text.*) *(.rtc_text_end_test) + /* Align the end of RTC code region as per PMP granularity */ + . = ALIGN(_esp_pmp_align_size); + _rtc_text_end = ABSOLUTE(.); } > lp_ram_seg @@ -166,6 +169,9 @@ SECTIONS /* Marks the end of IRAM code segment */ .iram0.text_end (NOLOAD) : { + /* Align the end of code region as per PMP region granularity */ + . = ALIGN(_esp_pmp_align_size); + ALIGNED_SYMBOL(4, _iram_text_end) } > sram_seg diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index 20851d554c3..4abdac04378 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -461,9 +461,12 @@ void IRAM_ATTR __attribute__((noreturn, no_sanitize_undefined)) panic_abort(cons #endif #endif - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-dereference") - *((volatile int *) 0) = 0; // NOLINT(clang-analyzer-core.NullDereference) should be an invalid operation on targets - ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-dereference") +#ifdef __XTENSA__ + asm("ill"); // should be an invalid operation on xtensa targets +#elif __riscv + asm("unimp"); // should be an invalid operation on RISC-V targets +#endif + while (1); } diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 798cd5e97df..ca0c15209c7 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -224,7 +224,7 @@ void IRAM_ATTR call_start_cpu1(void) #if CONFIG_ESP_CONSOLE_NONE esp_rom_install_channel_putc(1, NULL); esp_rom_install_channel_putc(2, NULL); -#else // CONFIG_ESP_CONSOLE_NONE +#elif !CONFIG_ESP_CONSOLE_USB_CDC esp_rom_install_uart_printf(); esp_rom_output_set_as_console(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM); #endif diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 7242255e4d4..674b92920e5 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -30,7 +30,6 @@ #include "esp_private/esp_pmu.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" -#include "ocode_init.h" /* Number of cycles to wait from the 32k XTAL oscillator to consider it running. * Larger values increase startup delay. Smaller values may cause false positive @@ -44,20 +43,13 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -// TODO: [ESP32C5] IDF-8642 void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA -#if SOC_PMU_SUPPORTED pmu_init(); -#endif - if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { - esp_ocode_calib_init(); - } #endif } -// TODO: [ESP32C5] IDF-8642 __attribute__((weak)) void esp_clk_init(void) { #if !CONFIG_IDF_ENV_FPGA @@ -122,7 +114,7 @@ __attribute__((weak)) void esp_clk_init(void) // Re calculate the ccount to make time calculation correct. esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz); - // Set crypto clock (`clk_sec`) to use 160M SPLL clock + // Set crypto clock (`clk_sec`) to use 480M SPLL clock REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2); } @@ -195,7 +187,8 @@ void rtc_clk_select_rtc_slow_clk(void) */ __attribute__((weak)) void esp_perip_clk_init(void) { - // TODO: [ESP32C5] IDF-8844 +// TODO: [ESP32C5] IDF-8844 +#if SOC_MODEM_CLOCK_SUPPORTED // modem_clock_domain_pmu_state_icg_map_init(); /* During system initialization, the low-power clock source of the modem * (WiFi, BLE or Coexist) follows the configuration of the slow clock source @@ -211,6 +204,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K : MODEM_CLOCK_LPCLK_SRC_RC32K); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); +#endif ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); #if 0 // TODO: [ESP32C5] IDF-8844 diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index 85332e67ae9..49f9737e8ef 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -41,7 +41,7 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -void esp_rtc_init(void) +void IRAM_ATTR esp_rtc_init(void) { #if SOC_PMU_SUPPORTED pmu_init(); diff --git a/components/esp_system/test_apps/.build-test-rules.yml b/components/esp_system/test_apps/.build-test-rules.yml index d35ca3820c7..e59aab60e35 100644 --- a/components/esp_system/test_apps/.build-test-rules.yml +++ b/components/esp_system/test_apps/.build-test-rules.yml @@ -6,9 +6,7 @@ components/esp_system/test_apps/console: components/esp_system/test_apps/esp_system_unity_tests: disable: - - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1) - temporary: true - reason: C5 not support yet # TODO: [ESP32C5] IDF-8690 + - if: (CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1) components/esp_system/test_apps/linux_apis: enable: diff --git a/components/esp_system/test_apps/esp_system_unity_tests/README.md b/components/esp_system/test_apps/esp_system_unity_tests/README.md index bf47d80ec64..3a502b1f86f 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/README.md +++ b/components/esp_system/test_apps/esp_system_unity_tests/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_reset_reason.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_reset_reason.c index f13473b237c..3008f15b62c 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_reset_reason.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_reset_reason.c @@ -28,76 +28,11 @@ #define CHECK_RTC_MEM 1 #endif //CONFIG_SOC_RTC_FAST_MEM_SUPPORTED || CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32 -#define DEEPSLEEP "DEEPSLEEP_RESET" -#define LOAD_STORE_ERROR "LoadStoreError" -#define RESET "SW_CPU_RESET" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "TG1WDT_SYS_RESET" -#define RTC_WDT "RTCWDT_RTC_RESET" -#if CONFIG_ESP32_REV_MIN_FULL >= 300 -#define BROWNOUT "RTCWDT_BROWN_OUT_RESET" +#if CONFIG_IDF_TARGET_ESP32P4 +#define INT_WDT_HW_ESP_RST ESP_RST_WDT // On P4 there is only one reset reason for MWDT0/1 #else -#define BROWNOUT "SW_CPU_RESET" -#endif // CONFIG_ESP32_REV_MIN_FULL >= 300 -#define STORE_ERROR "StoreProhibited" -#define INT_WDT_HW_ESP_RST ESP_RST_INT_WDT - -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 -#define DEEPSLEEP "DSLEEP" -#define LOAD_STORE_ERROR "LoadStoreError" -#define RESET "RTC_SW_CPU_RST" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "TG1WDT_SYS_RST" -#define RTC_WDT "RTCWDT_RTC_RST" -#define BROWNOUT "BROWN_OUT_RST" -#define STORE_ERROR "StoreProhibited" -#define INT_WDT_HW_ESP_RST ESP_RST_INT_WDT - -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 -#define DEEPSLEEP "DSLEEP" -#define LOAD_STORE_ERROR "Store access fault" -#define RESET "RTC_SW_CPU_RST" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "TG1WDT_SYS_RST" -#define RTC_WDT "RTCWDT_RTC_RST" -#define BROWNOUT "BROWNOUT_RST" -#define STORE_ERROR LOAD_STORE_ERROR -#define INT_WDT_HW_ESP_RST ESP_RST_INT_WDT -#elif CONFIG_IDF_TARGET_ESP32C2 -#define DEEPSLEEP "DSLEEP" -#define LOAD_STORE_ERROR "Store access fault" -#define RESET "RTC_SW_CPU_RST" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "TG0WDT_SYS_RST" -#define RTC_WDT "RTCWDT_RTC_RST" -#define BROWNOUT "BROWNOUT_RST" -#define STORE_ERROR LOAD_STORE_ERROR #define INT_WDT_HW_ESP_RST ESP_RST_INT_WDT - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define DEEPSLEEP "DSLEEP" -#define LOAD_STORE_ERROR "Store access fault" -#define RESET "SW_CPU" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "TG1_WDT_HPSYS" -#define RTC_WDT "LP_WDT_SYS" -#define BROWNOUT "LP_BOD_SYS" -#define STORE_ERROR LOAD_STORE_ERROR -#define INT_WDT_HW_ESP_RST ESP_RST_INT_WDT - -#elif CONFIG_IDF_TARGET_ESP32P4 -#define DEEPSLEEP "DSLEEP" -#define LOAD_STORE_ERROR "Store access fault" -#define RESET "SW_CPU_RESET" -#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" -#define INT_WDT "HP_SYS_HP_WDT_RESET" -#define RTC_WDT "LP_WDT_SYS" -#define BROWNOUT "LP_BOD_SYS" -#define STORE_ERROR LOAD_STORE_ERROR -#define INT_WDT_HW_ESP_RST ESP_RST_WDT // On P4 there is only one reset reason for MWDT0/1 - -#endif // CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_IDF_TARGET_ESP32P4 /* This test needs special test runners: rev1 silicon, and SPI flash with * fast start-up time. Otherwise reset reason will be RTCWDT_RESET. @@ -165,7 +100,7 @@ static void check_reset_reason_deep_sleep(void) } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_DEEPSLEEP", "[reset_reason][reset="DEEPSLEEP"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_DEEPSLEEP", "[reset_reason]", do_deep_sleep, check_reset_reason_deep_sleep); @@ -198,11 +133,11 @@ static void check_reset_reason_panic(void) #endif //CHECK_RTC_MEM } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after exception", "[reset_reason][reset="LOAD_STORE_ERROR","RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after exception", "[reset_reason]", do_exception, check_reset_reason_panic); -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after abort", "[reset_reason][reset=abort,"RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after abort", "[reset_reason]", do_abort, check_reset_reason_panic); @@ -236,12 +171,12 @@ static void check_reset_reason_sw(void) #endif //CHECK_RTC_MEM } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart", "[reset_reason][reset="RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart", "[reset_reason]", do_restart, check_reset_reason_sw); #if CONFIG_FREERTOS_NUMBER_OF_CORES > 1 -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart from APP CPU", "[reset_reason][reset="RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart from APP CPU", "[reset_reason]", do_restart_from_app_cpu, check_reset_reason_sw); #endif @@ -286,12 +221,12 @@ static void check_reset_reason_int_wdt_hw(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_INT_WDT after interrupt watchdog (panic)", - "[reset_reason][reset="INT_WDT_PANIC","RESET"]", + "[reset_reason]", do_int_wdt, check_reset_reason_int_wdt_sw); TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_INT_WDT after interrupt watchdog (hw)", - "[reset_reason][reset="INT_WDT"]", + "[reset_reason]", do_int_wdt_hw, check_reset_reason_int_wdt_hw); @@ -324,7 +259,7 @@ static void check_reset_reason_task_wdt(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_TASK_WDT after task watchdog", - "[reset_reason][reset="RESET"]", + "[reset_reason]", do_task_wdt, check_reset_reason_task_wdt); #endif // CONFIG_ESP_TASK_WDT_EN @@ -352,7 +287,7 @@ static void check_reset_reason_any_wdt(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_WDT after RTC watchdog", - "[reset_reason][reset="RTC_WDT"]", + "[reset_reason]", do_rtc_wdt, check_reset_reason_any_wdt); @@ -379,7 +314,7 @@ static void check_reset_reason_brownout(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event", - "[reset_reason][ignore][reset="BROWNOUT"]", + "[reset_reason][ignore]", do_brownout, check_reset_reason_brownout); @@ -457,11 +392,11 @@ static void test2_finish(void) printf("test - OK\n"); } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack][reset="RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack]", init_restart_task, test1_finish); -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a task with spiram stack", "[spiram_stack][reset="STORE_ERROR","RESET"]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a task with spiram stack", "[spiram_stack]", init_task_do_exception, test2_finish); diff --git a/components/esp_timer/test_apps/.build-test-rules.yml b/components/esp_timer/test_apps/.build-test-rules.yml deleted file mode 100644 index 748bc781b27..00000000000 --- a/components/esp_timer/test_apps/.build-test-rules.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps - -components/esp_timer/test_apps: - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: C5 not support yet # TODO: [ESP32C5] IDF-8705 diff --git a/components/esp_timer/test_apps/README.md b/components/esp_timer/test_apps/README.md index c75201fb88f..351f5fdebc7 100644 --- a/components/esp_timer/test_apps/README.md +++ b/components/esp_timer/test_apps/README.md @@ -1,3 +1,3 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index eacd07f165f..73ed5e75a6b 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit eacd07f165fee254b37ee5819208e1185549ec59 +Subproject commit 73ed5e75a6b8d456583c84428d3f3e3713c99944 diff --git a/components/esp_wifi/src/wifi_default.c b/components/esp_wifi/src/wifi_default.c index 6a687084c40..4d3acdc741a 100644 --- a/components/esp_wifi/src/wifi_default.c +++ b/components/esp_wifi/src/wifi_default.c @@ -465,8 +465,10 @@ esp_err_t esp_netif_create_default_wifi_mesh_netifs(esp_netif_t **p_netif_sta, e ESP_ERROR_CHECK(esp_netif_attach_wifi_ap(netif_ap)); ESP_ERROR_CHECK(esp_wifi_set_default_wifi_ap_handlers()); +#ifdef CONFIG_LWIP_DHCPS // ...and stop DHCP server to keep the ESP_NETIF_DHCP_STOPPED state ESP_ERROR_CHECK(esp_netif_dhcps_stop(netif_ap)); +#endif // Create "almost" default station, but with un-flagged DHCP client memcpy(&netif_cfg, ESP_NETIF_BASE_DEFAULT_WIFI_STA, sizeof(netif_cfg)); diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 0351cc16fb3..49661e1b795 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -3,8 +3,9 @@ menu "Serial flasher config" config ESPTOOLPY_NO_STUB bool "Disable download stub" - default "y" if IDF_ENV_FPGA || IDF_ENV_BRINGUP - default "n" + default y if IDF_ENV_FPGA || IDF_ENV_BRINGUP + default y if IDF_TARGET_ESP32C5 # TODO: IDF-8631 to be removed + default n help The flasher tool sends a precompiled download stub first by default. That stub allows things diff --git a/components/freertos/test_apps/.build-test-rules.yml b/components/freertos/test_apps/.build-test-rules.yml index 83c48f535d0..44a3a7d585e 100644 --- a/components/freertos/test_apps/.build-test-rules.yml +++ b/components/freertos/test_apps/.build-test-rules.yml @@ -2,9 +2,13 @@ components/freertos/test_apps/freertos: disable: - - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "smp" and IDF_TARGET == "esp32p4") + - if: CONFIG_NAME == "smp" and IDF_TARGET == "esp32p4" temporary: true - reason: target(s) not supported yet # TODO: [ESP32C5] IDF-8672 + reason: target(s) not supported yet + disable_test: + - if: CONFIG_NAME == "smp" and IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO: [ESP32C5] IDF-10335 components/freertos/test_apps/orig_inc_path: enable: diff --git a/components/freertos/test_apps/freertos/README.md b/components/freertos/test_apps/freertos/README.md index bf47d80ec64..3a502b1f86f 100644 --- a/components/freertos/test_apps/freertos/README.md +++ b/components/freertos/test_apps/freertos/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/freertos/test_apps/freertos/pytest_freertos.py b/components/freertos/test_apps/freertos/pytest_freertos.py index 6baa6ba7811..1bd8867d0b5 100644 --- a/components/freertos/test_apps/freertos/pytest_freertos.py +++ b/components/freertos/test_apps/freertos/pytest_freertos.py @@ -9,7 +9,9 @@ pytest.param('psram', marks=[pytest.mark.esp32]), pytest.param('release', marks=[pytest.mark.supported_targets]), pytest.param('single_core', marks=[pytest.mark.esp32, pytest.mark.esp32p4]), - pytest.param('smp', marks=[pytest.mark.supported_targets, pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4'], reason='test failed/TBD IDF-8113')]), + # TODO: [ESP32C5] IDF-10335 + pytest.param('smp', marks=[pytest.mark.supported_targets, pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4', 'esp32c5'], + reason='test failed/TBD IDF-8113')]), ] diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 6cc4319dc2c..0e9e12a6fcf 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -56,7 +56,7 @@ if(NOT BOOTLOADER_BUILD) endif() endif() - if(CONFIG_SOC_CLK_TREE_SUPPORTED OR CONFIG_IDF_TARGET_ESP32C5) # TODO: IDF-8642 + if(CONFIG_SOC_CLK_TREE_SUPPORTED) list(APPEND srcs "${target}/clk_tree_hal.c") endif() diff --git a/components/hal/esp32/include/hal/rmt_ll.h b/components/hal/esp32/include/hal/rmt_ll.h index 4e49d01f5fc..147c6c089db 100644 --- a/components/hal/esp32/include/hal/rmt_ll.h +++ b/components/hal/esp32/include/hal/rmt_ll.h @@ -88,14 +88,33 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->conf_ch[0].conf0.mem_pd = enable; // Only conf0 register of channel0 has `mem_pd` + (void)dev; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 1; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 0; } /** @@ -120,7 +139,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)divider_integral; (void)divider_denominator; @@ -631,7 +650,7 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { // Only conf0 register of channel0 has `mem_pd` return dev->conf_ch[0].conf0.mem_pd; diff --git a/components/hal/esp32c2/include/hal/aes_ll.h b/components/hal/esp32c2/include/hal/aes_ll.h deleted file mode 100644 index 2a38421e1b4..00000000000 --- a/components/hal/esp32c2/include/hal/aes_ll.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -/*************************************************************** - * - * This file needs to be removed. Left here just for passing build - * TODO // TODO: IDF-3844 - ***************************************************************/ -#pragma once - -#include -#include "soc/hwcrypto_reg.h" -#include "hal/aes_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief State of AES accelerator, busy, idle or done - * - */ -typedef enum { - ESP_AES_STATE_IDLE = 0, /* AES accelerator is idle */ - ESP_AES_STATE_BUSY, /* Transform in progress */ - ESP_AES_STATE_DONE, /* Transform completed */ -} esp_aes_state_t; - - -/** - * @brief Write the encryption/decryption key to hardware - * - * @param key Key to be written to the AES hardware - * @param key_word_len Number of words in the key - * - * @return volatile number of bytes written to hardware, used for fault injection check - */ -static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Sets the mode - * - * @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0 - * @param key_bytes Number of bytes in the key - */ -static inline void aes_ll_set_mode(int mode, uint8_t key_bytes) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Writes message block to AES hardware - * - * @param input Block to be written - */ -static inline void aes_ll_write_block(const void *input) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Read the AES block - * - * @param output the output of the transform, length = AES_BLOCK_BYTES - */ -static inline void aes_ll_read_block(void *output) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Starts block transform - * - */ -static inline void aes_ll_start_transform(void) -{ - abort(); // TODO: IDF-3844 -} - - -/** - * @brief Read state of AES accelerator - * - * @return esp_aes_state_t - */ -static inline esp_aes_state_t aes_ll_get_state(void) -{ - abort(); // TODO: IDF-3844 -} - - -/** - * @brief Set mode of operation - * - * @note Only used for DMA transforms - * - * @param mode - */ -static inline void aes_ll_set_block_mode(esp_aes_mode_t mode) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Set AES-CTR counter to INC32 - * - * @note Only affects AES-CTR mode - * - */ -static inline void aes_ll_set_inc(void) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Release the DMA - * - */ -static inline void aes_ll_dma_exit(void) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Sets the number of blocks to be transformed - * - * @note Only used for DMA transforms - * - * @param num_blocks Number of blocks to transform - */ -static inline void aes_ll_set_num_blocks(size_t num_blocks) -{ - abort(); // TODO: IDF-3844 -} - -/* - * Write IV to hardware iv registers - */ -static inline void aes_ll_set_iv(const uint8_t *iv) -{ - abort(); // TODO: IDF-3844 -} - -/* - * Read IV from hardware iv registers - */ -static inline void aes_ll_read_iv(uint8_t *iv) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Enable or disable DMA mode - * - * @param enable true to enable, false to disable. - */ -static inline void aes_ll_dma_enable(bool enable) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Enable or disable transform completed interrupt - * - * @param enable true to enable, false to disable. - */ -static inline void aes_ll_interrupt_enable(bool enable) -{ - abort(); // TODO: IDF-3844 -} - -/** - * @brief Clears the interrupt - * - */ -static inline void aes_ll_interrupt_clear(void) -{ - abort(); // TODO: IDF-3844 -} - - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32c3/include/hal/rmt_ll.h b/components/hal/esp32c3/include/hal/rmt_ll.h index 0bfe6d6609f..c76924fedf2 100644 --- a/components/hal/esp32c3/include/hal/rmt_ll.h +++ b/components/hal/esp32c3/include/hal/rmt_ll.h @@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -812,12 +833,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->tx_conf[channel].idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c5/clk_tree_hal.c b/components/hal/esp32c5/clk_tree_hal.c index de3b62e9fc9..b7ac7939f23 100644 --- a/components/hal/esp32c5/clk_tree_hal.c +++ b/components/hal/esp32c5/clk_tree_hal.c @@ -17,8 +17,10 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) switch (cpu_clk_src) { case SOC_CPU_CLK_SRC_XTAL: return clk_hal_xtal_get_freq_mhz(); - case SOC_CPU_CLK_SRC_PLL: - return clk_ll_bbpll_get_freq_mhz(); + case SOC_CPU_CLK_SRC_PLL_F160M: + return CLK_LL_PLL_160M_FREQ_MHZ; + case SOC_CPU_CLK_SRC_PLL_F240M: + return CLK_LL_PLL_240M_FREQ_MHZ; case SOC_CPU_CLK_SRC_RC_FAST: return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ; default: @@ -31,16 +33,14 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) uint32_t clk_hal_cpu_get_freq_hz(void) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); - uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_cpu_get_hs_divider() : clk_ll_cpu_get_ls_divider(); - + uint32_t divider = clk_ll_cpu_get_divider(); return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; } uint32_t clk_hal_ahb_get_freq_hz(void) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); - uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider(); - + uint32_t divider = clk_ll_ahb_get_divider(); return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; } diff --git a/components/hal/esp32c5/include/hal/clk_tree_ll.h b/components/hal/esp32c5/include/hal/clk_tree_ll.h index f1a9793efef..08eaa2747e5 100644 --- a/components/hal/esp32c5/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c5/include/hal/clk_tree_ll.h @@ -40,12 +40,8 @@ extern "C" { .dbuf = 1, \ } -/* -Set the frequency division factor of ref_tick -The FOSC of rtc calibration uses the 32 frequency division clock, -So the frequency division factor of ref_tick must be greater than or equal to 32 -*/ -#define REG_FOSC_TICK_NUM 255 // TODO: IDF-8642 No need? Can calibrate on RC_FAST directly? +// Fix default division factor for the RC_FAST clock for calibration to be 32 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 /** * @brief XTAL32K_CLK enable modes @@ -289,7 +285,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz( } /** - * @brief Set BBPLL frequency from XTAL source (Digital part) + * @brief Set SPLL frequency from XTAL source (Digital part) * * @param pll_freq_mhz PLL frequency, in MHz */ @@ -301,7 +297,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint } /** - * @brief Set BBPLL frequency from XTAL source (Analog part) + * @brief Set SPLL frequency from XTAL source (Analog part) * * @param pll_freq_mhz PLL frequency, in MHz * @param xtal_freq_mhz XTAL frequency, in MHz @@ -313,36 +309,52 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 uint8_t div7_0; uint8_t dr1; uint8_t dr3; - uint8_t dchgp; - uint8_t dbias; - uint8_t dcur; + uint8_t dchgp = 5; + uint8_t dbias = 3; + uint8_t href = 3; + uint8_t lref = 1; /* Configure 480M PLL */ switch (xtal_freq_mhz) { + case SOC_XTAL_FREQ_48M: + div_ref = 1; + div7_0 = 10; + dr1 = 1; + dr3 = 1; + break; case SOC_XTAL_FREQ_40M: + div_ref = 1; + div7_0 = 12; + dr1 = 0; + dr3 = 0; + break; default: - div_ref = 0; - div7_0 = 8; + div_ref = 1; + div7_0 = 12; dr1 = 0; dr3 = 0; - dchgp = 5; - dcur = 3; - dbias = 2; break; } - uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_div_7_0 = div7_0; - uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; - REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); - REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, lref); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, href); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); } +/** + * @brief To enable the change of soc_clk_sel, cpu_div_num, and ahb_div_num + */ +static inline __attribute__((always_inline)) void clk_ll_bus_update(void) +{ + PCR.bus_clk_update.bus_clock_update = 1; + while (PCR.bus_clk_update.bus_clock_update); +} + /** * @brief Select the clock source for CPU_CLK (SOC Clock Root) * @@ -354,12 +366,15 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk case SOC_CPU_CLK_SRC_XTAL: PCR.sysclk_conf.soc_clk_sel = 0; break; - case SOC_CPU_CLK_SRC_PLL: + case SOC_CPU_CLK_SRC_RC_FAST: PCR.sysclk_conf.soc_clk_sel = 1; break; - case SOC_CPU_CLK_SRC_RC_FAST: + case SOC_CPU_CLK_SRC_PLL_F160M: PCR.sysclk_conf.soc_clk_sel = 2; break; + case SOC_CPU_CLK_SRC_PLL_F240M: + PCR.sysclk_conf.soc_clk_sel = 3; + break; default: // Unsupported SOC_CLK mux input sel abort(); @@ -378,9 +393,11 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr case 0: return SOC_CPU_CLK_SRC_XTAL; case 1: - return SOC_CPU_CLK_SRC_PLL; - case 2: return SOC_CPU_CLK_SRC_RC_FAST; + case 2: + return SOC_CPU_CLK_SRC_PLL_F160M; + case 3: + return SOC_CPU_CLK_SRC_PLL_F240M; default: // Invalid SOC_CLK_SEL value return SOC_CPU_CLK_SRC_INVALID; @@ -388,129 +405,47 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr } /** - * @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * @brief Set CPU_CLK's divider * - * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider. + * @param divider Divider. (PCR_CPU_DIV_NUM + 1) = divider. */ -static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider) +static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider) { - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK - // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) - // Fixed at 3 for HS clock source - // Corresponding register field value is PCR_HS_DIV_NUM=2 - // (2) configurable - // HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3) - - HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider / 3) - 1); - - // 120MHz CPU freq cannot be achieved through divider, need to set force_120m - // This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL - // bool force_120m = (divider == 4) ? 1 : 0; - // PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m; + HAL_ASSERT(divider >= 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider) - 1); } /** - * @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) + * @brief Get CPU_CLK's divider * - * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider. + * @return Divider. Divider = (PCR_CPU_DIV_NUM + 1). */ -static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider) +static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void) { - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK - // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) - // Fixed at 1 for LS clock source - // Corresponding register field value is PCR_LS_DIV_NUM=0 - // (2) configurable - // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) - HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, divider - 1); + return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 1; } /** - * @brief Get CPU_CLK's high-speed divider + * @brief Set AHB_CLK's divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1). - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void) -{ - // uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force; - uint32_t cpu_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num); - if (cpu_hs_div == 0) { - return 4; - } - uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); - return (hp_root_hs_div + 1) * (cpu_hs_div + 1); -} - -/** - * @brief Get CPU_CLK's low-speed divider + * Constraint: f_ahb <= 48 MHz, f_cpu = n * f_ahb * - * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1). + * @param divider Divider. (PCR_AHB_DIV_NUM + 1) = divider. */ -static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void) +static inline __attribute__((always_inline)) void clk_ll_ahb_set_divider(uint32_t divider) { - uint32_t cpu_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num); - uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); - return (hp_root_ls_div + 1) * (cpu_ls_div + 1); -} - -/** - * @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) - * - * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider. - */ -static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK - // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) - // Fixed at 3 for HS clock source - // Corresponding register field value is PCR_HS_DIV_NUM=2 - // (2) configurable - // HS divider option: 4, 8, 16 (PCR_AHB_HS_DIV_NUM=3, 7, 15) - HAL_ASSERT(divider == 12 || divider == 24 || divider == 48); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, (divider / 3) - 1); -} - -/** - * @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) - * - * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider. - */ -static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK - // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) - // Fixed at 1 for LS clock source - // Corresponding register field value is PCR_LS_DIV_NUM=0 - // (2) configurable - // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) - HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); + HAL_ASSERT(divider >= 1); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, divider - 1); } /** - * @brief Get AHB_CLK's high-speed divider + * @brief Get AHB_CLK's divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1). + * @return Divider. Divider = (PCR_AHB_DIV_NUM + 1). */ -static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void) +static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_divider(void) { - uint32_t ahb_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num); - uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); - return (hp_root_hs_div + 1) * (ahb_hs_div + 1); -} - -/** - * @brief Get AHB_CLK's low-speed divider - * - * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1). - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void) -{ - uint32_t ahb_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num); - uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); - return (hp_root_ls_div + 1) * (ahb_ls_div + 1); + return HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num) + 1; } /** @@ -536,103 +471,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1; } -/** - * @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) - * - * @param divider Divider. - */ -static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ------> MSPI_FAST_CLK - // HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5) - uint32_t div_num = 0; - switch (divider) { - case 4: - div_num = 3; - break; - case 5: - div_num = 4; - break; - case 6: - div_num = 5; - break; - default: - // Unsupported HS MSPI_FAST divider - abort(); - } - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num); -} - -/** - * @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) - * - * @param divider Divider. - */ -static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ------> MSPI_FAST_CLK - // LS divider option: 1, 2, 4 (PCR_MSPI_FAST_LS_DIV_NUM=0, 1, 2) - uint32_t div_num = 0; - switch (divider) { - case 1: - div_num = 0; - break; - case 2: - div_num = 1; - break; - case 4: - div_num = 2; - break; - default: - // Unsupported LS MSPI_FAST divider - abort(); - } - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num); -} - -/** - * @brief Select the calibration 32kHz clock source for timergroup0 - * - * @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK) - */ -static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel) -{ - switch (in_sel) { - case SOC_RTC_SLOW_CLK_SRC_RC32K: - PCR.ctrl_32k_conf.clk_32k_sel = 0; - break; - case SOC_RTC_SLOW_CLK_SRC_XTAL32K: - PCR.ctrl_32k_conf.clk_32k_sel = 1; - break; - case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: - PCR.ctrl_32k_conf.clk_32k_sel = 2; - break; - default: - // Unsupported 32K_SEL mux input - abort(); - } -} - -/** - * @brief Get the calibration 32kHz clock source for timergroup0 - * - * @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks) - */ -static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void) -{ - uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel; - switch (clk_sel) { - case 0: - return SOC_RTC_SLOW_CLK_SRC_RC32K; - case 1: - return SOC_RTC_SLOW_CLK_SRC_XTAL32K; - case 2: - return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW; - default: - return SOC_RTC_SLOW_CLK_SRC_INVALID; - } -} - /** * @brief Select the clock source for RTC_SLOW_CLK * @@ -695,6 +533,9 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rt case SOC_RTC_FAST_CLK_SRC_XTAL_D2: LP_CLKRST.lp_clk_conf.fast_clk_sel = 1; break; + case SOC_RTC_FAST_CLK_SRC_XTAL: + LP_CLKRST.lp_clk_conf.fast_clk_sel = 2; + break; default: // Unsupported RTC_FAST_CLK mux input sel abort(); @@ -714,6 +555,8 @@ static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_f return SOC_RTC_FAST_CLK_SRC_RC_FAST; case 1: return SOC_RTC_FAST_CLK_SRC_XTAL_D2; + case 2: + return SOC_RTC_FAST_CLK_SRC_XTAL; default: return SOC_RTC_FAST_CLK_SRC_INVALID; } @@ -741,6 +584,14 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider return 1; } +/** + * @brief Set the frequency division factor of RC_FAST clock + */ +static inline void clk_ll_rc_fast_tick_conf(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_TICK_DIV_BITS +} + /** * @brief Set RC_SLOW_CLK divider * @@ -753,49 +604,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin } /************************** LP STORAGE REGISTER STORE/LOAD **************************/ -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION -/** - * @brief Store XTAL_CLK frequency in RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even, - * otherwise there will be a conflict with the low bit, which is used to disable logs - * in the ROM code. - */ -static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz) -{ - // Read the status of whether disabling logging from ROM code - uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG; - // If so, need to write back this setting - if (reg == RTC_DISABLE_ROM_LOG) { - xtal_freq_mhz |= 1; - } - WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16)); -} - -/** - * @brief Load XTAL_CLK frequency from RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid. - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void) -{ - // Read from RTC storage register - uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); - if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && - xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { - return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; - } - // If the format in reg is invalid - return 0; -} -#endif - /** * @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @@ -821,16 +629,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v return REG_READ(RTC_SLOW_CLK_CAL_REG); } - -/* -Set the frequency division factor of ref_tick -*/ -static inline void clk_ll_rc_fast_tick_conf(void) -{ - PCR.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM; -} - - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/efuse_ll.h b/components/hal/esp32c5/include/hal/efuse_ll.h index 8e283d1a7a0..414b241bd3a 100644 --- a/components/hal/esp32c5/include/hal/efuse_ll.h +++ b/components/hal/esp32c5/include/hal/efuse_ll.h @@ -18,6 +18,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -134,6 +143,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void /******************* eFuse control functions *************************/ +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/lpwdt_ll.h b/components/hal/esp32c5/include/hal/lpwdt_ll.h index c2c5008bae3..2df130e8f99 100644 --- a/components/hal/esp32c5/include/hal/lpwdt_ll.h +++ b/components/hal/esp32c5/include/hal/lpwdt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -68,9 +68,7 @@ ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == LP_WDT_RESET_LENGTH_3200_NS, "Ad */ FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_en = 1; - abort(); + hw->config0.wdt_en = 1; } /** @@ -83,9 +81,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_en = 0; - abort(); + hw->config0.wdt_en = 0; } /** @@ -96,10 +92,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // return (hw->config0.wdt_en) ? true : false; - abort(); - return (bool)0; + return (hw->config0.wdt_en) ? true : false; } /** @@ -122,29 +115,27 @@ FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior) { - // TODO: [ESP32C5] IDF-8635 - // switch (stage) { - // case WDT_STAGE0: - // hw->config0.wdt_stg0 = behavior; - // //Account of implicty multiplier applied to stage 0 timeout tick config value - // hw->config1.val = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL)); - // break; - // case WDT_STAGE1: - // hw->config0.wdt_stg1 = behavior; - // hw->config2.val = timeout_ticks; - // break; - // case WDT_STAGE2: - // hw->config0.wdt_stg2 = behavior; - // hw->config3.val = timeout_ticks; - // break; - // case WDT_STAGE3: - // hw->config0.wdt_stg3 = behavior; - // hw->config4.val = timeout_ticks; - // break; - // default: - // abort(); - // } - abort(); + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = behavior; + //Account of implicty multiplier applied to stage 0 timeout tick config value + hw->config1.val = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL)); + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = behavior; + hw->config2.val = timeout_ticks; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = behavior; + hw->config3.val = timeout_ticks; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = behavior; + hw->config4.val = timeout_ticks; + break; + default: + abort(); + } } /** @@ -155,24 +146,22 @@ FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage */ FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stage) { - // TODO: [ESP32C5] IDF-8635 - // switch (stage) { - // case WDT_STAGE0: - // hw->config0.wdt_stg0 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE1: - // hw->config0.wdt_stg1 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE2: - // hw->config0.wdt_stg2 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE3: - // hw->config0.wdt_stg3 = WDT_STAGE_ACTION_OFF; - // break; - // default: - // abort(); - // } - abort(); + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = WDT_STAGE_ACTION_OFF; + break; + default: + abort(); + } } /** @@ -183,9 +172,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stag */ FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_cpu_reset_length = length; - abort(); + hw->config0.wdt_cpu_reset_length = length; } /** @@ -196,9 +183,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset */ FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_sys_reset_length = length; - abort(); + hw->config0.wdt_sys_reset_length = length; } /** @@ -213,9 +198,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset */ FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_flashboot_mod_en = (enable) ? 1 : 0; - abort(); + hw->config0.wdt_flashboot_mod_en = (enable) ? 1 : 0; } /** @@ -226,9 +209,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_procpu_reset_en = (enable) ? 1 : 0; - abort(); + hw->config0.wdt_procpu_reset_en = (enable) ? 1 : 0; } /** @@ -239,9 +220,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enabl */ FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_appcpu_reset_en = (enable) ? 1 : 0; - abort(); + hw->config0.wdt_appcpu_reset_en = (enable) ? 1 : 0; } /** @@ -252,9 +231,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enabl */ FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_pause_in_slp = (enable) ? 1 : 0; - abort(); + hw->config0.wdt_pause_in_slp = (enable) ? 1 : 0; } /** @@ -268,9 +245,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool ena */ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_en(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->config0.wdt_chip_reset_en = (enable) ? 1 : 0; - abort(); + hw->config0.wdt_chip_reset_en = (enable) ? 1 : 0; } /** @@ -281,9 +256,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_en(lp_wdt_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t width) { - // TODO: [ESP32C5] IDF-8635 - // HAL_FORCE_MODIFY_U32_REG_FIELD(hw->config0, wdt_chip_reset_width, width); - abort(); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->config0, wdt_chip_reset_width, width); } /** @@ -295,9 +268,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t */ FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->feed.rtc_wdt_feed = 1; - abort(); + hw->feed.rtc_wdt_feed = 1; } /** @@ -307,9 +278,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->wprotect.val = 0; - abort(); + hw->wprotect.val = 0; } /** @@ -319,9 +288,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->wprotect.val = LP_WDT_WKEY_VALUE; - abort(); + hw->wprotect.val = LP_WDT_WKEY_VALUE; } /** @@ -332,9 +299,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8635 - // hw->int_ena.lp_wdt_int_ena = (enable) ? 1 : 0; - abort(); + hw->int_ena.lp_wdt_int_ena = (enable) ? 1 : 0; } /** @@ -345,10 +310,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // return (hw->int_st.lp_wdt_int_st) ? true : false; - abort(); - return (bool)0; + return (hw->int_st.lp_wdt_int_st) ? true : false; } /** @@ -358,9 +320,7 @@ FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_clear_intr_status(lp_wdt_dev_t *hw) { - // TODO: [ESP32C5] IDF-8635 - // hw->int_clr.lp_wdt_int_clr = 1; - abort(); + hw->int_clr.lp_wdt_int_clr = 1; } #ifdef __cplusplus diff --git a/components/hal/esp32c5/include/hal/mwdt_ll.h b/components/hal/esp32c5/include/hal/mwdt_ll.h index c4e386a6646..c4665a2eedf 100644 --- a/components/hal/esp32c5/include/hal/mwdt_ll.h +++ b/components/hal/esp32c5/include/hal/mwdt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,7 @@ extern "C" { #include "hal/misc.h" /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ -#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 +#define MWDT_LL_DEFAULT_CLK_PRESCALER 24000 /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 @@ -64,9 +64,7 @@ ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, " */ FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtconfig0.wdt_en = 1; - abort(); + hw->wdtconfig0.wdt_en = 1; } /** @@ -79,9 +77,7 @@ FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtconfig0.wdt_en = 0; - abort(); + hw->wdtconfig0.wdt_en = 0; } /** @@ -92,10 +88,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw) */ FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // return (hw->wdtconfig0.wdt_en) ? true : false; - abort(); - return (bool)0; + return (hw->wdtconfig0.wdt_en) ? true : false; } /** @@ -108,31 +101,29 @@ FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior) { - // TODO: [ESP32C5] IDF-8650 - // switch (stage) { - // case WDT_STAGE0: - // hw->wdtconfig0.wdt_stg0 = behavior; - // hw->wdtconfig2.wdt_stg0_hold = timeout; - // break; - // case WDT_STAGE1: - // hw->wdtconfig0.wdt_stg1 = behavior; - // hw->wdtconfig3.wdt_stg1_hold = timeout; - // break; - // case WDT_STAGE2: - // hw->wdtconfig0.wdt_stg2 = behavior; - // hw->wdtconfig4.wdt_stg2_hold = timeout; - // break; - // case WDT_STAGE3: - // hw->wdtconfig0.wdt_stg3 = behavior; - // hw->wdtconfig5.wdt_stg3_hold = timeout; - // break; - // default: - // HAL_ASSERT(false && "unsupported WDT stage"); - // break; - // } - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + switch (stage) { + case WDT_STAGE0: + hw->wdtconfig0.wdt_stg0 = behavior; + hw->wdtconfig2.wdt_stg0_hold = timeout; + break; + case WDT_STAGE1: + hw->wdtconfig0.wdt_stg1 = behavior; + hw->wdtconfig3.wdt_stg1_hold = timeout; + break; + case WDT_STAGE2: + hw->wdtconfig0.wdt_stg2 = behavior; + hw->wdtconfig4.wdt_stg2_hold = timeout; + break; + case WDT_STAGE3: + hw->wdtconfig0.wdt_stg3 = behavior; + hw->wdtconfig5.wdt_stg3_hold = timeout; + break; + default: + HAL_ASSERT(false && "unsupported WDT stage"); + break; + } + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -143,27 +134,25 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u */ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage) { - // TODO: [ESP32C5] IDF-8650 - // switch (stage) { - // case WDT_STAGE0: - // hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE1: - // hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE2: - // hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE3: - // hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; - // break; - // default: - // HAL_ASSERT(false && "unsupported WDT stage"); - // break; - // } - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + switch (stage) { + case WDT_STAGE0: + hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE1: + hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE2: + hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE3: + hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; + break; + default: + HAL_ASSERT(false && "unsupported WDT stage"); + break; + } + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -174,11 +163,9 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage) */ FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtconfig0.wdt_cpu_reset_length = length; - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + hw->wdtconfig0.wdt_cpu_reset_length = length; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -189,11 +176,9 @@ FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_si */ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtconfig0.wdt_sys_reset_length = length; - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + hw->wdtconfig0.wdt_sys_reset_length = length; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -208,11 +193,9 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si */ FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0; - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0; + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -223,13 +206,11 @@ FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler) { - // TODO: [ESP32C5] IDF-8650 - // // In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register) - // // We take care of the "read-modify-write" procedure by ourselves. - // HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig1, wdt_clk_prescale, prescaler); - // //Config registers are updated asynchronously - // hw->wdtconfig0.wdt_conf_update_en = 1; - abort(); + // In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register) + // We take care of the "read-modify-write" procedure by ourselves. + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig1, wdt_clk_prescale, prescaler); + //Config registers are updated asynchronously + hw->wdtconfig0.wdt_conf_update_en = 1; } /** @@ -241,9 +222,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler) */ FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtfeed.wdt_feed = 1; - abort(); + hw->wdtfeed.wdt_feed = 1; } /** @@ -255,9 +234,7 @@ FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtwprotect.wdt_wkey = 0; - abort(); + hw->wdtwprotect.wdt_wkey = 0; } /** @@ -267,9 +244,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE; - abort(); + hw->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE; } /** @@ -279,9 +254,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw) { - // TODO: [ESP32C5] IDF-8650 - // hw->int_clr_timers.wdt_int_clr = 1; - abort(); + hw->int_clr_timers.wdt_int_clr = 1; } /** @@ -292,9 +265,7 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw) */ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable) { - // TODO: [ESP32C5] IDF-8650 - // hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0; - abort(); + hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0; } /** @@ -305,28 +276,27 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src) { - // TODO: [ESP32C5] IDF-8650 - // uint8_t clk_id = 0; - // switch (clk_src) { - // case MWDT_CLK_SRC_XTAL: - // clk_id = 0; - // break; - // case MWDT_CLK_SRC_PLL_F80M: - // clk_id = 1; - // break; - // case MWDT_CLK_SRC_RC_FAST: - // clk_id = 2; - // break; - // default: - // HAL_ASSERT(false); - // break; - // } - // // if (hw == &TIMERG0) { - // PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_sel = clk_id; - // } else { - // PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_sel = clk_id; - // } - abort(); + uint8_t clk_id = 0; + switch (clk_src) { + case MWDT_CLK_SRC_XTAL: + clk_id = 0; + break; + case MWDT_CLK_SRC_PLL_F80M: + clk_id = 1; + break; + case MWDT_CLK_SRC_RC_FAST: + clk_id = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + if (hw == &TIMERG0) { + PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_sel = clk_id; + } else { + PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_sel = clk_id; + } } /** @@ -338,13 +308,11 @@ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_sourc __attribute__((always_inline)) static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en) { - // TODO: [ESP32C5] IDF-8650 - // if (hw == &TIMERG0) { - // PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_en = en; - // } else { - // PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_en = en; - // } - abort(); + if (hw == &TIMERG0) { + PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_en = en; + } else { + PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_en = en; + } } diff --git a/components/hal/esp32c5/include/hal/pcnt_ll.h b/components/hal/esp32c5/include/hal/pcnt_ll.h index ddf151b677f..adce8964888 100644 --- a/components/hal/esp32c5/include/hal/pcnt_ll.h +++ b/components/hal/esp32c5/include/hal/pcnt_ll.h @@ -33,6 +33,12 @@ typedef enum { PCNT_LL_WATCH_EVENT_MAX } pcnt_ll_watch_event_id_t; +typedef enum { + PCNT_LL_STEP_EVENT_REACH_LIMIT = PCNT_LL_WATCH_EVENT_MAX, + PCNT_LL_STEP_EVENT_REACH_INTERVAL +} pcnt_ll_step_event_id_t; + +#define PCNT_LL_STEP_NOTIFY_DIR_LIMIT 1 #define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1) #define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id)) diff --git a/components/hal/esp32c5/include/hal/rmt_ll.h b/components/hal/esp32c5/include/hal/rmt_ll.h index b4b0e32f8a0..5e488cf52aa 100644 --- a/components/hal/esp32c5/include/hal/rmt_ll.h +++ b/components/hal/esp32c5/include/hal/rmt_ll.h @@ -79,15 +79,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + PCR.rmt_pd_ctrl.rmt_mem_force_pu = 1; + PCR.rmt_pd_ctrl.rmt_mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + PCR.rmt_pd_ctrl.rmt_mem_force_pd = 1; + PCR.rmt_pd_ctrl.rmt_mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + PCR.rmt_pd_ctrl.rmt_mem_force_pd = 0; + PCR.rmt_pd_ctrl.rmt_mem_force_pu = 0; } /** @@ -112,7 +133,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { // Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b) (void)channel; // the source clock is set for all channels @@ -818,12 +839,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return PCR.rmt_pd_ctrl.rmt_mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c5/include/hal/rtc_io_ll.h b/components/hal/esp32c5/include/hal/rtc_io_ll.h index ef2eb7bcf63..7b3d10819cf 100644 --- a/components/hal/esp32c5/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c5/include/hal/rtc_io_ll.h @@ -16,8 +16,10 @@ #include #include "soc/soc_caps.h" #include "soc/pcr_struct.h" -// #include "soc/lp_io_struct.h" -// #include "soc/lp_aon_struct.h" +#include "soc/lp_iomux_struct.h" +#include "soc/lp_aon_struct.h" +#include "soc/lp_gpio_struct.h" +#include "soc/lpperi_struct.h" #include "soc/pmu_struct.h" #include "hal/misc.h" #include "hal/assert.h" @@ -26,7 +28,7 @@ extern "C" { #endif -#define RTCIO_LL_PIN_FUNC 0 +#define RTCIO_LL_PIN_FUNC 1 typedef enum { RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ @@ -39,11 +41,6 @@ typedef enum { RTCIO_LL_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ } rtcio_ll_wake_type_t; -typedef enum { - RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ - RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ -} rtcio_ll_out_mode_t; - typedef enum { RTCIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ RTCIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ @@ -53,6 +50,11 @@ typedef enum { RTCIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ } rtcio_ll_intr_type_t; +typedef enum { + RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ + RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ +} rtcio_ll_out_mode_t; + /** * @brief Select a RTC IOMUX function for the RTC IO * @@ -61,11 +63,24 @@ typedef enum { */ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].mcu_sel = func; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_sel = func; } +/** + * @brief Enable/Disable LP_GPIO peripheral clock. + * + * @param enable true to enable the clock / false to disable the clock + */ +static inline void _rtcio_ll_enable_io_clock(bool enable) +{ + LPPERI.clk_en.lp_io_ck_en = enable; + while (LPPERI.clk_en.lp_io_ck_en != enable) { + ; + } +} + +#define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) + /** * @brief Select the rtcio function. * @@ -78,21 +93,19 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) */ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) { - // TODO: [ESP32C5] IDF-8719 - // if (func == RTCIO_LL_FUNC_RTC) { - // // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. - // uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); - // sel_mask |= BIT(rtcio_num); - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); - // //0:RTC FUNCTION 1,2,3:Reserved - // rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC); - // } else if (func == RTCIO_LL_FUNC_DIGITAL) { - // // Clear the bit to use digital GPIO module - // uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); - // sel_mask &= ~BIT(rtcio_num); - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); - // } - abort(); + if (func == RTCIO_LL_FUNC_RTC) { + // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask |= BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + // LP_GPIO is FUNC 1 + rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC); + } else if (func == RTCIO_LL_FUNC_DIGITAL) { + // Clear the bit to use digital GPIO module + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask &= ~BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + } } /** @@ -102,9 +115,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) */ static inline void rtcio_ll_output_enable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1ts, enable_w1ts, BIT(rtcio_num)); - abort(); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, enable_w1ts, BIT(rtcio_num)); } /** @@ -114,9 +125,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num) */ static inline void rtcio_ll_output_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1tc, enable_w1tc, BIT(rtcio_num)); - abort(); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, enable_w1tc, BIT(rtcio_num)); } /** @@ -127,13 +136,11 @@ static inline void rtcio_ll_output_disable(int rtcio_num) */ static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) { - // TODO: [ESP32C5] IDF-8719 - // if (level) { - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_data_w1ts, BIT(rtcio_num)); - // } else { - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_data_w1tc, BIT(rtcio_num)); - // } - abort(); + if (level) { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, out_w1ts, BIT(rtcio_num)); + } else { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, out_w1tc, BIT(rtcio_num)); + } } /** @@ -143,9 +150,7 @@ static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) */ static inline void rtcio_ll_input_enable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].fun_ie = 1; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 1; } /** @@ -155,9 +160,7 @@ static inline void rtcio_ll_input_enable(int rtcio_num) */ static inline void rtcio_ll_input_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].fun_ie = 0; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 0; } /** @@ -168,10 +171,7 @@ static inline void rtcio_ll_input_disable(int rtcio_num) */ static inline uint32_t rtcio_ll_get_level(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // return (uint32_t)(HAL_FORCE_READ_U32_REG_FIELD(LP_IO.in, in_data_next) >> rtcio_num) & 0x1; - abort(); - return (uint32_t)0; + return (uint32_t)(HAL_FORCE_READ_U32_REG_FIELD(LP_GPIO.in, in_data_next) >> rtcio_num) & 0x1; } /** @@ -182,9 +182,7 @@ static inline uint32_t rtcio_ll_get_level(int rtcio_num) */ static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].fun_drv = strength; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv = strength; } /** @@ -195,10 +193,7 @@ static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strengt */ static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // return LP_IO.gpio[rtcio_num].fun_drv; - abort(); - return (uint32_t)0; + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv; } /** @@ -209,9 +204,7 @@ static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) */ static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.pin[rtcio_num].pad_driver = mode; - abort(); + LP_GPIO.pinn[rtcio_num].pinn_pad_driver = mode; } /** @@ -221,10 +214,8 @@ static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t m */ static inline void rtcio_ll_pullup_enable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // /* Enable internal weak pull-up */ - // LP_IO.gpio[rtcio_num].fun_wpu = 1; - abort(); + /* Enable internal weak pull-up */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 1; } /** @@ -234,10 +225,8 @@ static inline void rtcio_ll_pullup_enable(int rtcio_num) */ static inline void rtcio_ll_pullup_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // /* Disable internal weak pull-up */ - // LP_IO.gpio[rtcio_num].fun_wpu = 0; - abort(); + /* Disable internal weak pull-up */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 0; } /** @@ -247,10 +236,8 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num) */ static inline void rtcio_ll_pulldown_enable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // /* Enable internal weak pull-down */ - // LP_IO.gpio[rtcio_num].fun_wpd = 1; - abort(); + /* Enable internal weak pull-down */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 1; } /** @@ -260,10 +247,8 @@ static inline void rtcio_ll_pulldown_enable(int rtcio_num) */ static inline void rtcio_ll_pulldown_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // /* Enable internal weak pull-down */ - // LP_IO.gpio[rtcio_num].fun_wpd = 0; - abort(); + /* Enable internal weak pull-down */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 0; } /** @@ -278,9 +263,7 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num) */ static inline void rtcio_ll_force_hold_enable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num); - abort(); + LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num); } /** @@ -291,9 +274,7 @@ static inline void rtcio_ll_force_hold_enable(int rtcio_num) */ static inline void rtcio_ll_force_hold_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num); - abort(); + LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num); } /** @@ -306,9 +287,7 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num) */ static inline void rtcio_ll_force_hold_all(void) { - // TODO: [ESP32C5] IDF-8719 - // PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; - abort(); + PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; } /** @@ -318,9 +297,7 @@ static inline void rtcio_ll_force_hold_all(void) */ static inline void rtcio_ll_force_unhold_all(void) { - // TODO: [ESP32C5] IDF-8719 - // PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; - abort(); + PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; } /** @@ -331,10 +308,8 @@ static inline void rtcio_ll_force_unhold_all(void) */ static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.pin[rtcio_num].wakeup_enable = 1; - // LP_IO.pin[rtcio_num].int_type = type; - abort(); + LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 1; + LP_GPIO.pinn[rtcio_num].pinn_int_type = type; } /** @@ -344,10 +319,26 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t ty */ static inline void rtcio_ll_wakeup_disable(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.pin[rtcio_num].wakeup_enable = 0; - // LP_IO.pin[rtcio_num].int_type = RTCIO_LL_WAKEUP_DISABLE; - abort(); + LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 0; + LP_GPIO.pinn[rtcio_num].pinn_int_type = RTCIO_LL_WAKEUP_DISABLE; +} + +/** + * Enable interrupt function and set interrupt type + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Interrupt type on high level or low level. + */ + +static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type) +{ + LP_GPIO.pinn[rtcio_num].pinn_int_type = type; + + /* Work around for HW issue, + need to also enable this clk, so that LP_GPIO.status.status_interrupt can get updated, + and trigger the interrupt on the LP Core + */ + LP_GPIO.clock_gate.clk_en = 1; } /** @@ -357,9 +348,7 @@ static inline void rtcio_ll_wakeup_disable(int rtcio_num) */ static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].mcu_oe = 1; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 1; } /** @@ -369,9 +358,7 @@ static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num) */ static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].mcu_oe = 0; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 0; } /** @@ -381,9 +368,7 @@ static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num) */ static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].mcu_ie = 1; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 1; } /** @@ -393,9 +378,7 @@ static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num) */ static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].mcu_ie = 0; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 0; } /** @@ -405,9 +388,7 @@ static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num) */ static inline void rtcio_ll_enable_sleep_setting(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].slp_sel = 1; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 1; } /** @@ -417,9 +398,7 @@ static inline void rtcio_ll_enable_sleep_setting(int rtcio_num) */ static inline void rtcio_ll_disable_sleep_setting(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // LP_IO.gpio[rtcio_num].slp_sel = 0; - abort(); + LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 0; } /** @@ -430,11 +409,8 @@ static inline void rtcio_ll_disable_sleep_setting(int rtcio_num) */ static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num) { - // TODO: [ESP32C5] IDF-8719 - // HAL_ASSERT(rtcio_num >= 0 && rtcio_num < SOC_RTCIO_PIN_COUNT && "io does not support deep sleep wake-up function"); - // return LP_IO.pin[rtcio_num].wakeup_enable; - abort(); - return (bool)0; + HAL_ASSERT(rtcio_num >= 0 && rtcio_num < SOC_RTCIO_PIN_COUNT && "io does not support deep sleep wake-up function"); + return LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable; } /** @@ -444,10 +420,7 @@ static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num) */ static inline uint32_t rtcio_ll_get_interrupt_status(void) { - // TODO: [ESP32C5] IDF-8719 - // return (uint32_t)HAL_FORCE_READ_U32_REG_FIELD(LP_IO.status, status_interrupt); - abort(); - return (uint32_t)0; + return (uint32_t)HAL_FORCE_READ_U32_REG_FIELD(LP_GPIO.status, status_interrupt); } /** @@ -455,21 +428,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void) */ static inline void rtcio_ll_clear_interrupt_status(void) { - // TODO: [ESP32C5] IDF-8719 - // HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_w1tc, 0xff); - abort(); -} - -/** - * Enable interrupt function and set interrupt type - * - * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). - * @param type Interrupt type on high level or low level. - */ -static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type) -{ - // TODO: [ESP32C5] IDF-8719 - //LP_GPIO.pin[rtcio_num].int_type = type; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, status_w1tc, 0xff); } #ifdef __cplusplus diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index 9fe36292ac0..30aa05e1ada 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -44,7 +44,8 @@ Set the frequency division factor of ref_tick The FOSC of rtc calibration uses the 32 frequency division clock for ECO1, So the frequency division factor of ref_tick must be greater than or equal to 32 */ -#define REG_FOSC_TICK_NUM 255 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 +#define REG_FOSC_TICK_NUM 255 /** * @brief XTAL32K_CLK enable modes @@ -810,7 +811,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock } diff --git a/components/hal/esp32c6/include/hal/efuse_ll.h b/components/hal/esp32c6/include/hal/efuse_ll.h index fc687bc9dec..c7d5f4a0bbc 100644 --- a/components/hal/esp32c6/include/hal/efuse_ll.h +++ b/components/hal/esp32c6/include/hal/efuse_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -175,6 +184,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint1 EFUSE.wr_tim_conf2.pwr_off_num = value; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32c6/include/hal/rmt_ll.h b/components/hal/esp32c6/include/hal/rmt_ll.h index e097afdee16..247d63e5fe8 100644 --- a/components/hal/esp32c6/include/hal/rmt_ll.h +++ b/components/hal/esp32c6/include/hal/rmt_ll.h @@ -82,15 +82,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -821,12 +842,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c61/include/hal/clk_tree_ll.h b/components/hal/esp32c61/include/hal/clk_tree_ll.h index 4ad88dccbbf..8ed04659a10 100644 --- a/components/hal/esp32c61/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c61/include/hal/clk_tree_ll.h @@ -808,7 +808,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // divider = (REG_FOSC_TICK_NUM + 1) = 256 } diff --git a/components/hal/esp32h2/include/hal/clk_tree_ll.h b/components/hal/esp32h2/include/hal/clk_tree_ll.h index f862b5a1286..f5946077283 100644 --- a/components/hal/esp32h2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32h2/include/hal/clk_tree_ll.h @@ -43,7 +43,8 @@ Set the frequency division factor of ref_tick The FOSC of rtc calibration uses the 32 frequency division clock for ECO2, So the frequency division factor of ref_tick must be greater than or equal to 32 */ -#define REG_FOSC_TICK_NUM 255 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 +#define REG_FOSC_TICK_NUM 255 /** * @brief XTAL32K_CLK enable modes @@ -746,7 +747,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock } /* diff --git a/components/hal/esp32h2/include/hal/rmt_ll.h b/components/hal/esp32h2/include/hal/rmt_ll.h index a99b41e58dd..a3179addba5 100644 --- a/components/hal/esp32h2/include/hal/rmt_ll.h +++ b/components/hal/esp32h2/include/hal/rmt_ll.h @@ -82,15 +82,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -815,12 +836,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32p4/include/hal/efuse_ll.h b/components/hal/esp32p4/include/hal/efuse_ll.h index 3032dd041b8..c287b964dc6 100644 --- a/components/hal/esp32p4/include/hal/efuse_ll.h +++ b/components/hal/esp32p4/include/hal/efuse_ll.h @@ -16,6 +16,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -130,6 +139,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void EFUSE.wr_tim_conf0_rs_bypass.update = 1; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/rmt_ll.h b/components/hal/esp32p4/include/hal/rmt_ll.h index d7830865b80..affcc3eeacd 100644 --- a/components/hal/esp32p4/include/hal/rmt_ll.h +++ b/components/hal/esp32p4/include/hal/rmt_ll.h @@ -87,7 +87,7 @@ static inline void rmt_ll_reset_register(int group_id) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)dev; // Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b) @@ -145,15 +145,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -862,12 +883,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32p4/include/hal/spi_ll.h b/components/hal/esp32p4/include/hal/spi_ll.h index 645d5dbd0bf..e45f4845497 100644 --- a/components/hal/esp32p4/include/hal/spi_ll.h +++ b/components/hal/esp32p4/include/hal/spi_ll.h @@ -42,6 +42,7 @@ extern "C" { #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words #define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral #define SPI_LL_CLK_SRC_PRE_DIV_MAX 512//div1(8bit) * div2(8bit but set const 2) +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -880,6 +881,16 @@ static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int dela { } +/** + * Determine and unify the default level of mosi line when bus free + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) +{ + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state +} + /** * Set the miso delay applied to the input signal before the internal peripheral. (Preview) * diff --git a/components/hal/esp32p4/include/hal/touch_sensor_ll.h b/components/hal/esp32p4/include/hal/touch_sensor_ll.h index e63fb9d465f..37280c3b5d2 100644 --- a/components/hal/esp32p4/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32p4/include/hal/touch_sensor_ll.h @@ -755,10 +755,10 @@ static inline void touch_ll_filter_enable(bool enable) */ static inline void touch_ll_force_update_benchmark(uint32_t benchmark) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_filter3, touch_baseline_sw, benchmark); - LP_ANA_PERI.touch_filter3.touch_update_baseline_sw = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_filter3, touch_benchmark_sw, benchmark); + LP_ANA_PERI.touch_filter3.touch_update_benchmark_sw = 1; // waiting for update - while (LP_ANA_PERI.touch_filter3.touch_update_baseline_sw); + while (LP_ANA_PERI.touch_filter3.touch_update_benchmark_sw); } /************************ Waterproof register setting ************************/ diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index bfe78f5a0fa..98eb39dfe05 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -90,15 +90,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->apb_conf.mem_force_pu = !enable; - dev->apb_conf.mem_force_pd = enable; + dev->apb_conf.mem_force_pu = 1; + dev->apb_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 1; + dev->apb_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 0; + dev->apb_conf.mem_force_pu = 0; } /** @@ -774,12 +795,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->apb_conf.mem_force_pd) || !(dev->apb_conf.mem_force_pu); + return dev->apb_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32s3/include/hal/rmt_ll.h b/components/hal/esp32s3/include/hal/rmt_ll.h index 13601630b47..e999add0260 100644 --- a/components/hal/esp32s3/include/hal/rmt_ll.h +++ b/components/hal/esp32s3/include/hal/rmt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -850,12 +871,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/include/hal/pcnt_types.h b/components/hal/include/hal/pcnt_types.h index 8af94e879eb..78372a3171d 100644 --- a/components/hal/include/hal/pcnt_types.h +++ b/components/hal/include/hal/pcnt_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/rmt_hal.c b/components/hal/rmt_hal.c index ea9565e7a60..7290d36b1f2 100644 --- a/components/hal/rmt_hal.c +++ b/components/hal/rmt_hal.c @@ -10,7 +10,7 @@ void rmt_hal_init(rmt_hal_context_t *hal) { hal->regs = &RMT; - rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain + rmt_ll_mem_power_by_pmu(hal->regs); rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events @@ -23,7 +23,7 @@ void rmt_hal_deinit(rmt_hal_context_t *hal) { rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events - rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain + rmt_ll_mem_force_power_off(hal->regs); // power off RMTMEM power domain forcefully hal->regs = NULL; } diff --git a/components/hal/test_apps/crypto/main/CMakeLists.txt b/components/hal/test_apps/crypto/main/CMakeLists.txt index 3f7585a3aaf..c9644c852e9 100644 --- a/components/hal/test_apps/crypto/main/CMakeLists.txt +++ b/components/hal/test_apps/crypto/main/CMakeLists.txt @@ -21,6 +21,12 @@ if(CONFIG_SOC_ECDSA_SUPPORTED) list(APPEND srcs "ecdsa/test_ecdsa.c") endif() +if(CONFIG_SOC_KEY_MANAGER_SUPPORTED) + list(APPEND srcs "key_manager/test_key_manager.c" + "$ENV{IDF_PATH}/components/esp_hw_support/esp_key_mgr.c") + list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/esp_hw_support/include") +endif() + if(CONFIG_SOC_AES_SUPPORTED) list(APPEND srcs "aes/test_aes.c" "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_common.c" @@ -68,7 +74,7 @@ if(CONFIG_SOC_SHA_SUPPORTED) endif() idf_component_register(SRCS ${srcs} - PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support + PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support spi_flash REQUIRES test_utils unity WHOLE_ARCHIVE PRIV_INCLUDE_DIRS "${priv_include_dirs}" diff --git a/components/hal/test_apps/crypto/main/app_main.c b/components/hal/test_apps/crypto/main/app_main.c index 6708b7a7685..460445a343a 100644 --- a/components/hal/test_apps/crypto/main/app_main.c +++ b/components/hal/test_apps/crypto/main/app_main.c @@ -30,6 +30,10 @@ static void run_all_tests(void) #endif /* !CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG*/ #endif +#if CONFIG_SOC_KEY_MANAGER_SUPPORTED + RUN_TEST_GROUP(key_manager); +#endif + #if CONFIG_IDF_ENV_FPGA #if CONFIG_SOC_HMAC_SUPPORTED && CONFIG_CRYPTO_TEST_APP_ENABLE_HMAC_TESTS diff --git a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c index 2a7e1d4239b..343304bd77a 100644 --- a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c +++ b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c @@ -72,7 +72,7 @@ static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len } } -static int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y) +int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y) { uint16_t len; uint8_t sha_le[32]; @@ -139,7 +139,7 @@ static void test_ecdsa_corrupt_data(bool is_p256, uint8_t* sha, uint8_t* r_le, u } -static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type) +void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type) { uint8_t sha_le[32] = {0}; uint8_t zeroes[32] = {0}; @@ -201,7 +201,7 @@ static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* ecdsa_disable(); } -static void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type) +void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type) { uint8_t r_le[32] = {0}; uint8_t s_le[32] = {0}; @@ -211,13 +211,10 @@ static void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_ } #ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY -static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key) +void test_ecdsa_export_pubkey_inner(bool is_p256, uint8_t *exported_pub_x, uint8_t *exported_pub_y, bool use_km_key, uint16_t *len) { - uint8_t pub_x[32] = {0}; - uint8_t pub_y[32] = {0}; - uint8_t zeroes[32] = {0}; - uint16_t len; + uint8_t zeroes[32] = {0}; ecdsa_hal_config_t conf = { .mode = ECDSA_MODE_EXPORT_PUBKEY, .use_km_key = use_km_key, @@ -228,13 +225,13 @@ static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key) if (use_km_key == 0) { conf.efuse_key_blk = EFUSE_BLK_KEY0 + ECDSA_KEY_BLOCK_2; } - len = 32; + *len = 32; } else { conf.curve = ECDSA_CURVE_SECP192R1; if (use_km_key == 0) { conf.efuse_key_blk = EFUSE_BLK_KEY0 + ECDSA_KEY_BLOCK_1; } - len = 24; + *len = 24; } ecdsa_enable_and_reset(); @@ -242,24 +239,28 @@ static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key) bool process_again = false; do { - ecdsa_hal_export_pubkey(&conf, pub_x, pub_y, len); + ecdsa_hal_export_pubkey(&conf, exported_pub_x, exported_pub_y, *len); process_again = !ecdsa_hal_get_operation_result() - || !memcmp(pub_x, zeroes, len) - || !memcmp(pub_y, zeroes, len); + || !memcmp(exported_pub_x, zeroes, *len) + || !memcmp(exported_pub_y, zeroes, *len); } while (process_again); - if (is_p256) { - TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa256_pub_x, pub_x, len); - TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa256_pub_y, pub_y, len); - } else { - TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa192_pub_x, pub_x, len); - TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa192_pub_y, pub_y, len); - } - ecdsa_disable(); } + +void test_ecdsa_export_pubkey(bool is_p256, uint8_t *ecdsa_pub_x, uint8_t *ecdsa_pub_y, bool use_km_key) +{ + uint8_t pub_x[32] = {0}; + uint8_t pub_y[32] = {0}; + uint16_t len; + test_ecdsa_export_pubkey_inner(is_p256, pub_x, pub_y, use_km_key, &len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa_pub_x, pub_x, len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa_pub_y, pub_y, len); + +} #endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */ @@ -322,12 +323,12 @@ TEST(ecdsa, ecdsa_SECP256R1_det_sign_and_verify) #ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY TEST(ecdsa, ecdsa_SECP192R1_export_pubkey) { - test_ecdsa_export_pubkey(0, 0); + test_ecdsa_export_pubkey(0, ecdsa192_pub_x, ecdsa192_pub_y, 0); } TEST(ecdsa, ecdsa_SECP256R1_export_pubkey) { - test_ecdsa_export_pubkey(1, 0); + test_ecdsa_export_pubkey(1, ecdsa256_pub_x, ecdsa256_pub_y, 0); } #endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */ diff --git a/components/hal/test_apps/crypto/main/key_manager/gen_key_manager_test_cases.py b/components/hal/test_apps/crypto/main/key_manager/gen_key_manager_test_cases.py new file mode 100644 index 00000000000..fb2419e716b --- /dev/null +++ b/components/hal/test_apps/crypto/main/key_manager/gen_key_manager_test_cases.py @@ -0,0 +1,257 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import os +import struct +from typing import Any + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.ciphers import algorithms +from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers import modes +from ecdsa.curves import NIST256p + +# Constants +TEST_COUNT = 5 + + +# Helper functions +def generate_random_key(size: int = 32) -> bytes: + return os.urandom(size) + + +def save_key_to_file(key: bytes, filename: str) -> None: + with open(filename, 'wb') as file: + file.write(key) + + +def key_from_file_or_generate(filename: str, size: int = 32) -> bytes: + if not os.path.exists(filename): + key = generate_random_key(size) + save_key_to_file(key, filename) + + with open(filename, 'rb') as file: + return file.read() + + +def key_to_c_format(key: bytes) -> str: + return ', '.join([f'0x{byte:02x}' for byte in key]) + + +def calculate_aes_cipher(data: bytes, key: bytes) -> Any: + cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) + encryptor = cipher.encryptor() + return encryptor.update(data) + encryptor.finalize() + + +def _flash_encryption_operation_aes_xts(input_data: bytes, flash_address: int, key: bytes, do_decrypt: bool = False) -> bytes: + backend = default_backend() + + indata = input_data + + pad_left = flash_address % 0x80 + indata = (b'\x00' * pad_left) + indata + + pad_right = (0x80 - (len(indata) % 0x80)) % 0x80 + indata += (b'\x00' * pad_right) + + inblocks = [indata[i:i + 0x80] for i in range(0, len(indata), 0x80)] + + output = b'' + for inblock in inblocks: + tweak = struct.pack(' list: + xts_test_data = [] + plaintext_data = bytes(range(1, 129)) + data_size = 16 + flash_address = base_flash_address + for i in range(TEST_COUNT): + data_size = (data_size * 2) % 256 + if (data_size < 16): + data_size = 16 + input_data = plaintext_data[:data_size] + flash_address = base_flash_address + (i * 0x100) + + ciphertext = _flash_encryption_operation_aes_xts(input_data, flash_address, key) + xts_test_data.append((data_size, flash_address, ciphertext[:data_size])) + return xts_test_data + + +def generate_ecdsa_256_key_and_pub_key(filename: str) -> tuple: + with open(filename, 'rb') as f: + private_number = int.from_bytes(f.read(), byteorder='big') + + private_key = ec.derive_private_key(private_number, ec.SECP256R1()) + pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption() + ) + + with open('ecdsa_256_key.pem', 'wb') as pem_file: + pem_file.write(pem) + + public_key = private_key.public_key() + pub_numbers = public_key.public_numbers() + pubx = pub_numbers.x.to_bytes(32, byteorder='little') + puby = pub_numbers.y.to_bytes(32, byteorder='little') + + return pubx, puby + + +def perform_ecc_point_multiplication(k1_int: int) -> Any: + generator = NIST256p.generator.to_affine() + k1_G = k1_int * generator + return k1_G + + +def generate_k1_G(key_file_path: str) -> tuple: + k1_G = [] + if os.path.exists(key_file_path): + with open(key_file_path, 'rb') as key_file: + k1_bytes = key_file.read() + + k1_int = int.from_bytes(k1_bytes, byteorder='big') + k1_G_point = perform_ecc_point_multiplication(k1_int) + k1_G = k1_G_point.to_bytes()[:64] + + k1_G = k1_G[::-1] + k1_G_x = k1_G[:32] + k1_G_y = k1_G[32:] + k1_G = k1_G_y + k1_G_x + + return k1_G, k1_G + + +def write_to_c_header(init_key: bytes, k1: bytes, k2_info: bytes, k1_encrypted_32: list, + test_data_xts_aes_128: list, k1_encrypted_64: list, + xts_test_data_xts_aes_256: list, pubx: bytes, + puby: bytes, k1_G_0: bytes, k1_G_1: bytes) -> None: + with open('key_manager_test_cases.h', 'w') as file: + header_content = """#include + +#define TEST_COUNT 5 + +typedef struct test_xts_data { + uint16_t data_size; + uint32_t data_offset; + uint8_t ciphertext[128]; +} test_xts_data_t; + +typedef struct test_ecdsa_data { + uint8_t pubx[32]; + uint8_t puby[32]; +} test_ecdsa_data_t; + +typedef struct test_data { + uint8_t init_key[32]; + uint8_t k2_info[64]; + uint8_t k1_encrypted[2][32]; // For both 256-bit and 512-bit keys + uint8_t plaintext_data[128]; + test_xts_data_t xts_test_data[TEST_COUNT]; + test_ecdsa_data_t ecdsa_test_data; +} test_data_aes_mode_t; + +typedef struct test_data_ecdh0 { + uint8_t plaintext_data[128]; + uint8_t k1[2][32]; + uint8_t k1_G[2][64]; +} test_data_ecdh0_mode_t; + +// For 32-byte k1 key +test_data_aes_mode_t test_data_xts_aes_128 = { + .init_key = { %s }, + .k2_info = { %s }, + .k1_encrypted = { { %s }, { } }, + .plaintext_data = { %s }, + .xts_test_data = { +""" % (key_to_c_format(init_key), key_to_c_format(k2_info), key_to_c_format(k1_encrypted_32[0]), key_to_c_format(bytes(range(1, 129)))) + + for data_size, flash_address, ciphertext in test_data_xts_aes_128: + header_content += f'\t\t{{.data_size = {data_size}, .data_offset = 0x{flash_address:x}, .ciphertext = {{{key_to_c_format(ciphertext)}}}}},\n' + header_content += '\t}\n};\n\n' + + # For 64-byte k1 key + header_content += '// For 64-byte k1 key\n' + header_content += 'test_data_aes_mode_t test_data_xts_aes_256 = {\n' + header_content += f'\t.init_key = {{{key_to_c_format(init_key)}}},\n' + header_content += f'\t.k2_info = {{{key_to_c_format(k2_info)}}},\n' + header_content += f'\t.k1_encrypted = {{{{{key_to_c_format(k1_encrypted_64[0])}}}, {{{key_to_c_format(k1_encrypted_64[1])}}}}},\n' + header_content += f'\t.plaintext_data = {{{key_to_c_format(bytes(range(1, 129)))}}},\n' + header_content += ' .xts_test_data = {\n' + + for data_size, flash_address, ciphertext in xts_test_data_xts_aes_256: + header_content += f' {{.data_size = {data_size}, .data_offset = 0x{flash_address:x}, .ciphertext = {{{key_to_c_format(ciphertext)}}}}},\n' + header_content += ' }\n};\n' + header_content += ''' +test_data_aes_mode_t test_data_ecdsa = { + .init_key = { %s }, + .k2_info = { %s }, + .k1_encrypted = { { %s }, { } }, + .ecdsa_test_data = { + .pubx = { %s }, + .puby = { %s } + } +};\n +''' % (key_to_c_format(init_key), key_to_c_format(k2_info), key_to_c_format(k1_encrypted_32[0]), key_to_c_format(pubx),key_to_c_format(puby)) + header_content += ''' +test_data_ecdh0_mode_t test_data_ecdh0 = { + .plaintext_data = { %s }, + .k1 = { + { %s }, + { %s }, + }, + .k1_G = { + { %s }, + { %s }, + } +};\n + +''' % (key_to_c_format(bytes(range(1, 129))), key_to_c_format(k1), key_to_c_format(k1), key_to_c_format(k1_G_0), key_to_c_format(k1_G_1)) + + file.write(header_content) + + +# Main script logic follows as per your provided structure +init_key = key_from_file_or_generate('init_key.bin', 32) +k2 = key_from_file_or_generate('k2.bin', 32) +rand_num = key_from_file_or_generate('rand_num.bin', 32) + +temp_result_inner = calculate_aes_cipher(k2, rand_num) +temp_result_outer = calculate_aes_cipher(temp_result_inner + rand_num, init_key) +k2_info = temp_result_outer + +k1_32 = key_from_file_or_generate('k1.bin', 32) +k1_64 = key_from_file_or_generate('k1_64.bin', 64) + +k1_32_reversed = k1_32[::-1] + +k1_64_reversed = k1_64[::-1] + +k1_64_1 = k1_64[:32] +k1_64_1_reversed = k1_64_1[::-1] +k1_64_2 = k1_64[32:] +k1_64_2_reversed = k1_64_2[::-1] + +k1_encrypted_32 = [calculate_aes_cipher(k1_32_reversed, k2)] +k1_encrypted_64 = [calculate_aes_cipher(k1_64_1_reversed, k2), calculate_aes_cipher(k1_64_2_reversed, k2)] + +test_data_xts_aes_128 = generate_xts_test_data(k1_32) +xts_test_data_xts_aes_256 = generate_xts_test_data(k1_64) + +pubx, puby = generate_ecdsa_256_key_and_pub_key('k1.bin') + +k1_G_0, k1_G_1 = generate_k1_G('k1.bin') + +write_to_c_header(init_key, k1_32, k2_info, k1_encrypted_32, test_data_xts_aes_128, k1_encrypted_64, xts_test_data_xts_aes_256, pubx, puby, k1_G_0, k1_G_1) diff --git a/components/hal/test_apps/crypto/main/key_manager/key_manager_test_cases.h b/components/hal/test_apps/crypto/main/key_manager/key_manager_test_cases.h new file mode 100644 index 00000000000..6a7a2abf7a7 --- /dev/null +++ b/components/hal/test_apps/crypto/main/key_manager/key_manager_test_cases.h @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include + +#define TEST_COUNT 5 + +typedef struct test_xts_data { + uint16_t data_size; + uint32_t data_offset; + uint8_t ciphertext[128]; +} test_xts_data_t; + +typedef struct test_ecdsa_data { + uint8_t pubx[32]; + uint8_t puby[32]; +} test_ecdsa_data_t; + +typedef struct test_data { + uint8_t init_key[32]; + uint8_t k2_info[64]; + uint8_t k1_encrypted[2][32]; // For both 256-bit and 512-bit keys + uint8_t plaintext_data[128]; + test_xts_data_t xts_test_data[TEST_COUNT]; + test_ecdsa_data_t ecdsa_test_data; +} test_data_aes_mode_t; + +typedef struct test_data_ecdh0 { + uint8_t plaintext_data[128]; + uint8_t k1[2][32]; + uint8_t k1_G[2][64]; +} test_data_ecdh0_mode_t; + +// For 32-byte k1 key +test_data_aes_mode_t test_data_xts_aes_128 = { + .init_key = { 0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93 }, + .k2_info = { 0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3 }, + .k1_encrypted = { { 0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48 }, { } }, + .plaintext_data = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80 }, + .xts_test_data = { + {.data_size = 32, .data_offset = 0x120000, .ciphertext = {0xe7, 0xf3, 0xb4, 0x51, 0xc6, 0x62, 0x8e, 0x25, 0x10, 0x12, 0xc2, 0x09, 0x82, 0x7b, 0x3e, 0x9a, 0x78, 0xe2, 0x00, 0x9a, 0x96, 0x02, 0x50, 0xeb, 0xff, 0xf1, 0xf8, 0x0d, 0xf6, 0xa6, 0xb8, 0xa1}}, + {.data_size = 64, .data_offset = 0x120100, .ciphertext = {0x3b, 0x54, 0xa8, 0x58, 0xe2, 0x63, 0x7a, 0xb0, 0x7c, 0xc7, 0x37, 0xd8, 0x1e, 0x89, 0x1e, 0x25, 0x39, 0x3d, 0x0d, 0x18, 0x14, 0xb3, 0x2e, 0x18, 0x15, 0xf6, 0xbd, 0xf8, 0xb6, 0x5f, 0x6b, 0x89, 0x1a, 0x0a, 0x53, 0x36, 0xf1, 0x5b, 0x1b, 0x18, 0xd3, 0xf4, 0x7b, 0xd5, 0xcd, 0x4f, 0x48, 0x7b, 0x11, 0xcf, 0xad, 0x6b, 0x79, 0x36, 0x1b, 0xda, 0x5a, 0xd3, 0x18, 0x44, 0xa0, 0xf3, 0xf2, 0xad}}, + {.data_size = 128, .data_offset = 0x120200, .ciphertext = {0x6b, 0x42, 0x10, 0x9f, 0x67, 0x72, 0x31, 0xc7, 0x8f, 0x63, 0xde, 0xc1, 0xf9, 0x84, 0x37, 0x74, 0xe5, 0x5a, 0xe4, 0x31, 0x1a, 0x2e, 0x45, 0x6b, 0xb5, 0xd4, 0xd0, 0x41, 0xe1, 0x2c, 0x0a, 0x43, 0xd9, 0x4c, 0xd5, 0x1c, 0x34, 0xc9, 0x29, 0x39, 0xc8, 0x09, 0xc3, 0xcd, 0x99, 0xaf, 0x3a, 0xe6, 0x4d, 0xae, 0xce, 0xfd, 0x0a, 0xd4, 0x8f, 0x81, 0x4c, 0x25, 0xc5, 0x5e, 0x3d, 0x82, 0x3d, 0x58, 0x55, 0xe5, 0xa4, 0xe4, 0x13, 0x2b, 0xa0, 0x04, 0x3a, 0x7a, 0x65, 0xfa, 0x7a, 0xfb, 0x28, 0x36, 0x1e, 0xfa, 0x71, 0x50, 0x80, 0xa5, 0x0c, 0xa6, 0x4e, 0x45, 0xf9, 0xd9, 0x05, 0xc1, 0x63, 0xa1, 0xf2, 0x7f, 0x54, 0x62, 0xf1, 0x5a, 0xe2, 0x5a, 0x5c, 0x06, 0x16, 0x71, 0xa9, 0x5f, 0xab, 0x7d, 0xc9, 0x85, 0x68, 0xc5, 0x3a, 0xfe, 0xc1, 0xe0, 0xc9, 0xc3, 0xd4, 0x33, 0x10, 0x89, 0x5e, 0x43}}, + {.data_size = 16, .data_offset = 0x120300, .ciphertext = {0xbe, 0xd7, 0x01, 0x8a, 0x60, 0xab, 0x0c, 0xb7, 0xb6, 0x14, 0x9e, 0x64, 0xbc, 0xca, 0xda, 0xaa}}, + {.data_size = 32, .data_offset = 0x120400, .ciphertext = {0xda, 0x84, 0x17, 0x3d, 0x4c, 0x85, 0x07, 0xe2, 0x56, 0x98, 0x69, 0x33, 0x1b, 0x9a, 0x01, 0x9e, 0x6c, 0x81, 0xd8, 0x90, 0x9e, 0x59, 0x92, 0x12, 0x6d, 0xba, 0x58, 0x09, 0x90, 0xe6, 0x50, 0x33}}, + } +}; + +// For 64-byte k1 key +test_data_aes_mode_t test_data_xts_aes_256 = { + .init_key = {0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93}, + .k2_info = {0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3}, + .k1_encrypted = {{0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48}, {0x65, 0x9e, 0x12, 0x7f, 0xc0, 0x4a, 0xb6, 0x04, 0xa1, 0xd0, 0x38, 0x04, 0x6c, 0x8e, 0x1f, 0xc7, 0x03, 0x24, 0x3e, 0x75, 0x3c, 0x9d, 0x7a, 0xc2, 0xef, 0xd6, 0xf2, 0x60, 0x46, 0xfc, 0x07, 0x3f}}, + .plaintext_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80}, + .xts_test_data = { + {.data_size = 32, .data_offset = 0x120000, .ciphertext = {0x9b, 0xd8, 0x2b, 0xc6, 0xae, 0xcc, 0x9d, 0x0c, 0x38, 0x30, 0x85, 0x6a, 0x2b, 0x22, 0x2e, 0x34, 0x9f, 0xa2, 0xcd, 0xe8, 0xec, 0xe3, 0xc4, 0x21, 0xfe, 0xbb, 0x4a, 0x55, 0xf2, 0x4a, 0xe2, 0x14}}, + {.data_size = 64, .data_offset = 0x120100, .ciphertext = {0x1e, 0x36, 0x3f, 0xf6, 0xd6, 0x52, 0x34, 0xce, 0xc3, 0x58, 0x15, 0xa1, 0x15, 0x6f, 0x3d, 0x66, 0xa7, 0x90, 0x14, 0x71, 0xbb, 0x6d, 0x7e, 0x93, 0xf2, 0x4d, 0x5d, 0x74, 0xb2, 0xd7, 0x77, 0x32, 0x2e, 0x31, 0x16, 0x28, 0xd2, 0x10, 0x65, 0x81, 0x49, 0xc0, 0x56, 0xf0, 0x6d, 0x71, 0x5b, 0xc2, 0xf2, 0x01, 0x04, 0xbf, 0x97, 0x77, 0xe6, 0x57, 0xe5, 0xb5, 0xad, 0x73, 0xc0, 0x76, 0x91, 0xb6}}, + {.data_size = 128, .data_offset = 0x120200, .ciphertext = {0xcf, 0x7d, 0xdd, 0x69, 0x69, 0xf4, 0x3b, 0xcd, 0x65, 0x5d, 0xcf, 0xfc, 0xff, 0xd3, 0x45, 0x1c, 0x51, 0xab, 0x2e, 0x26, 0x5c, 0xdc, 0x5b, 0x5a, 0x6e, 0xbb, 0x18, 0x36, 0x55, 0xbe, 0xe7, 0x30, 0x7a, 0x07, 0x48, 0xd8, 0x1a, 0x34, 0xdc, 0xa6, 0x1e, 0xd6, 0x67, 0xa8, 0x90, 0xc3, 0xac, 0x26, 0x7a, 0x52, 0x67, 0x82, 0x71, 0xc9, 0x80, 0x8d, 0xed, 0x20, 0x83, 0x34, 0x10, 0x8e, 0xe5, 0x84, 0x81, 0xa5, 0xe2, 0x42, 0xf0, 0x53, 0xef, 0x93, 0x00, 0xfe, 0xbd, 0x74, 0x14, 0xac, 0x92, 0x37, 0x00, 0x45, 0xd5, 0x71, 0x29, 0xaf, 0x8b, 0x83, 0xe2, 0x20, 0x2e, 0xd0, 0xf6, 0xaa, 0x45, 0x9a, 0x6f, 0x59, 0xb9, 0x8d, 0xef, 0xcd, 0xb6, 0xf6, 0x25, 0x99, 0xd2, 0x32, 0x2e, 0x90, 0x8a, 0x3a, 0x5d, 0xd8, 0x3f, 0xbf, 0x84, 0x80, 0x89, 0xaa, 0x9c, 0xa8, 0x57, 0xc9, 0x1c, 0xc4, 0xaa, 0x64}}, + {.data_size = 16, .data_offset = 0x120300, .ciphertext = {0x1b, 0x7a, 0xf1, 0x35, 0x33, 0x22, 0x64, 0x74, 0x06, 0x6a, 0xc1, 0x0c, 0x39, 0xee, 0x1f, 0x9f}}, + {.data_size = 32, .data_offset = 0x120400, .ciphertext = {0x94, 0xd9, 0x01, 0x0f, 0xec, 0xcc, 0xb5, 0x22, 0x50, 0x8b, 0x8a, 0x3d, 0x01, 0x18, 0x29, 0xda, 0x53, 0x9b, 0xcf, 0x64, 0xac, 0x4f, 0x7b, 0x97, 0xf3, 0xff, 0xfd, 0x33, 0x96, 0x8a, 0xde, 0x27}}, + } +}; + +test_data_aes_mode_t test_data_ecdsa = { + .init_key = { 0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93 }, + .k2_info = { 0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3 }, + .k1_encrypted = { { 0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48 }, { } }, + .ecdsa_test_data = { + .pubx = { 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21 }, + .puby = { 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 } + } +}; + + +test_data_ecdh0_mode_t test_data_ecdh0 = { + .plaintext_data = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80 }, + .k1 = { + { 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }, + { 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }, + }, + .k1_G = { + { 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21, 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 }, + { 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21, 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 }, + } +}; diff --git a/components/hal/test_apps/crypto/main/key_manager/test_key_manager.c b/components/hal/test_apps/crypto/main/key_manager/test_key_manager.c new file mode 100644 index 00000000000..ca424eb1321 --- /dev/null +++ b/components/hal/test_apps/crypto/main/key_manager/test_key_manager.c @@ -0,0 +1,374 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include + +#include "esp_efuse_chip.h" +#include "esp_heap_caps.h" +#include "esp_rom_crc.h" +#include "hal/key_mgr_hal.h" +#include "hal/key_mgr_ll.h" +#include "hal/key_mgr_types.h" +#include "hal/huk_types.h" +#include "hal/huk_hal.h" +#include "esp_key_mgr.h" +#include "memory_checks.h" +#include "unity_fixture.h" +#include "hal_crypto_common.h" +#include "rom/key_mgr.h" +#include "esp_partition.h" +#include "esp_flash.h" +#include "key_manager_test_cases.h" +#include "esp_log.h" + +// For ECDSA tests +#include "hal/ecdsa_hal.h" + +const esp_partition_t *get_test_storage_partition(void) +{ + /* This finds "storage" partition defined partition table */ + const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_ANY, "storage"); + if (!result) { + /* means partition table set wrong */ + printf("ERROR in obtaining storage partition"); + return NULL; + } + return result; +} + +static void print_data_in_hex(const uint8_t *data, int size, const char *info_str) +{ + printf("%s: 0x", info_str); + for(int i = 0 ; i < size; i++) { + printf("%02x", data[i]); + } + printf("\n"); +} + +static void test_xts_aes_key_aes_mode(test_data_aes_mode_t *test_data) +{ + const esp_partition_t *partition = get_test_storage_partition(); + ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); + + for (int i = 0; i < TEST_COUNT; i++) { + uint32_t address = test_data->xts_test_data[i].data_offset; + uint32_t data_size = test_data->xts_test_data[i].data_size; + ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size)); + static uint8_t read_data[128]; + ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test_data->xts_test_data[i].ciphertext, read_data, data_size); + } +} + +static void test_xts_aes_key_ecdh0_mode(test_data_ecdh0_mode_t *test_data) +{ + const esp_partition_t *partition = get_test_storage_partition(); + ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); + + uint32_t address = partition->address; + uint32_t data_size = 32; + + print_data_in_hex(test_data->plaintext_data, data_size, "Plaintext data"); + + ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size)); + static uint8_t read_data[128]; + ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size)); + print_data_in_hex(read_data, data_size, "Encrypted data"); +} + +static void key_mgr_test_xts_aes_128(void) +{ + static esp_key_mgr_aes_key_config_t key_config; + memcpy(key_config.k2_info, (uint8_t*) test_data_xts_aes_128.k2_info, KEY_MGR_K2_INFO_SIZE); + memcpy(key_config.k1_encrypted, (uint8_t*) test_data_xts_aes_128.k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE); + memcpy(key_config.sw_init_key, (uint8_t*) test_data_xts_aes_128.init_key, KEY_MGR_SW_INIT_KEY_SIZE); + key_config.use_pre_generated_sw_init_key = 1; + key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info)); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_aes_mode(&test_data_xts_aes_128); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); + +} + +static void key_mgr_test_xts_aes_256_aes_mode(void) +{ + static esp_key_mgr_aes_key_config_t key_config; + memcpy(key_config.k2_info, (uint8_t*) test_data_xts_aes_256.k2_info, KEY_MGR_K2_INFO_SIZE); + memcpy(key_config.k1_encrypted[0], (uint8_t*) test_data_xts_aes_256.k1_encrypted[0], KEY_MGR_K1_ENCRYPTED_SIZE); + memcpy(key_config.k1_encrypted[1], (uint8_t*) test_data_xts_aes_256.k1_encrypted[1], KEY_MGR_K1_ENCRYPTED_SIZE); + memcpy(key_config.sw_init_key, (uint8_t*) test_data_xts_aes_256.init_key, KEY_MGR_SW_INIT_KEY_SIZE); + key_config.use_pre_generated_sw_init_key = 1; + key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info)); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_aes_mode(&test_data_xts_aes_256); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY +extern void test_ecdsa_export_pubkey(bool is_p256, uint8_t *ecdsa_pub_x, uint8_t *ecdsa_pub_y, bool use_km_key); +extern void test_ecdsa_export_pubkey_inner(bool is_p256, uint8_t *exported_pub_x, uint8_t *exported_pub_y, bool use_km_key, uint16_t *len); +#endif + +extern void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type); + +/* +const uint8_t message[32] = { 0xDF, 0xDE, 0xD7, 0x4A, 0x47, 0xB1, 0x4F, 0x73, 0x00, 0x21, 0x62, 0xC7, 0x66, 0x6D, 0xA3, 0x95, 0x66, 0x19, 0x62, 0x7F, 0x71, 0x7B, 0x3C, 0x66, 0x82, 0xD3, 0x9F, 0x71, 0xAC, 0x9C, 0xC3, 0x39 }; +*/ + +/* sha256 digest of the above message */ +uint8_t sha256_digest[32] = { 0x47, 0xA6, 0xEF, 0xBE, 0x39, 0x5E, 0xE4, 0xAE, 0x2B, 0xEC, 0x83, 0xB1, 0xED, 0xAF, 0xC6, 0x78, 0x57, 0x7A, 0x16, 0x8C, 0x22, 0x16, 0x13, 0xE2, 0xAC, 0xA8, 0x50, 0xD5, 0x67, 0x95, 0x9F, 0x71 }; + +void test_ecdsa_key_aes_mode(test_data_aes_mode_t *ecdsa_test_data, ecdsa_sign_type_t k_type) +{ + test_ecdsa_sign_and_verify(1, sha256_digest, ecdsa_test_data->ecdsa_test_data.pubx, ecdsa_test_data->ecdsa_test_data.puby, 1, k_type); +#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY + test_ecdsa_export_pubkey(1, ecdsa_test_data->ecdsa_test_data.pubx, ecdsa_test_data->ecdsa_test_data.puby, 1); +#endif +} + + +extern void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type); + +extern int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y); + +void key_mgr_test_ecdsa_key(bool is_p256, ecdsa_sign_type_t k_type) +{ + uint8_t pub_x[32] = {}; + uint8_t pub_y[32] = {}; + uint8_t r_le[32] = {0}; + uint8_t s_le[32] = {0}; + + test_ecdsa_sign(is_p256, sha256_digest, r_le, s_le, 1, k_type); + + print_data_in_hex(sha256_digest, sizeof(sha256_digest), "ECDSA message sha256 digest"); + print_data_in_hex(r_le, sizeof(r_le), "ECDSA signature r_le"); + print_data_in_hex(s_le, sizeof(s_le), "ECDSA signature s_le"); + + // Export the pubkey from ECDSA peripheral + uint16_t pubkey_len = 0; + test_ecdsa_export_pubkey_inner(is_p256, pub_x, pub_y, 1, &pubkey_len); + + print_data_in_hex(pub_x, pubkey_len, "ECDSA key pubx"); + print_data_in_hex(pub_y, pubkey_len, "ECDSA key puby"); + TEST_ASSERT_EQUAL(0, test_ecdsa_verify(is_p256, sha256_digest, r_le, s_le, pub_x, pub_y)); + +} + +static void key_mgr_test_ecdsa_p256_aes_mode(void) +{ + static esp_key_mgr_aes_key_config_t key_config; + memcpy(key_config.k2_info, (uint8_t*) test_data_ecdsa.k2_info, KEY_MGR_K2_INFO_SIZE); + memcpy(key_config.k1_encrypted, (uint8_t*) test_data_ecdsa.k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE); + memcpy(key_config.sw_init_key, (uint8_t*) test_data_ecdsa.init_key, KEY_MGR_SW_INIT_KEY_SIZE); + key_config.use_pre_generated_sw_init_key = 1; + key_config.key_type = ESP_KEY_MGR_ECDSA_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info)); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); +#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE + test_ecdsa_key_aes_mode(&test_data_ecdsa, ECDSA_K_TYPE_DETERMINISITIC); +#endif + test_ecdsa_key_aes_mode(&test_data_ecdsa, ECDSA_K_TYPE_TRNG); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +static void key_mgr_test_xts_aes_128_ecdh0_mode(void) +{ + printf("\nKey Manager ECDH0 deployment: XTS_AES_128 key\n"); + static esp_key_mgr_ecdh0_key_config_t key_config; + memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE); + key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + static esp_key_mgr_ecdh0_info_t ecdh0_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info)); + + print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G"); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_ecdh0_mode(&test_data_ecdh0); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +static void key_mgr_test_xts_aes_256_ecdh0_mode(void) +{ + printf("\nKey Manager ECDH0 deployment: XTS_AES_256 key\n"); + static esp_key_mgr_ecdh0_key_config_t key_config; + memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE); + memcpy(key_config.k1_G[1], (uint8_t*) test_data_ecdh0.k1_G[1], KEY_MGR_ECDH0_INFO_SIZE); + key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + static esp_key_mgr_ecdh0_info_t ecdh0_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info)); + + print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G_0"); + print_data_in_hex(ecdh0_info.k2_G[1], KEY_MGR_ECDH0_INFO_SIZE, "K2_G_1"); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_ecdh0_mode(&test_data_ecdh0); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +static void key_mgr_test_ecdsa_ecdh0_mode(void) +{ + printf("\nKey Manager ECDH0 deployment: ECDSA_256 key\n"); + static esp_key_mgr_ecdh0_key_config_t key_config; + memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE); + key_config.key_type = ESP_KEY_MGR_ECDSA_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + static esp_key_mgr_ecdh0_info_t ecdh0_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info)); + + print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G"); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); +#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE + key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_DETERMINISITIC); +#endif + key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_TRNG); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +static void key_mgr_test_ecdsa_random_mode(void) +{ + printf("\nKey Manager Random deployment: ECDSA_256 key\n"); + static esp_key_mgr_random_key_config_t key_config; + key_config.key_type = ESP_KEY_MGR_ECDSA_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info)); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + +#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE + key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_DETERMINISITIC); +#endif + key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_TRNG); + + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} + +#if CONFIG_IDF_ENV_FPGA + +static void test_xts_aes_key_random_mode(void) +{ + const esp_partition_t *partition = get_test_storage_partition(); + ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); + uint8_t plaintext_data[1024] = {[0 ... 1023] = 0xBE}; + const int write_size = 16; + for (int i = 0; i < sizeof(plaintext_data) / write_size; i++) { + printf("\n i = %d\n", i); + ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, partition->address + (i * write_size), plaintext_data, write_size)); + static uint8_t read_data[128]; + ESP_ERROR_CHECK(esp_partition_read(partition, write_size * i, read_data, write_size)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext_data + (i * write_size), read_data, write_size); + } +} + + +static void key_mgr_test_xts_aes_128_random_mode(void) +{ + static esp_key_mgr_random_key_config_t key_config; + key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY; + + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info)); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_random_mode(); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); + +} + +static void key_mgr_test_xts_aes_256_random_mode(void) +{ + static esp_key_mgr_random_key_config_t key_config; + key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY; + static esp_key_mgr_key_recovery_info_t key_recovery_info; + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info)); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); + test_xts_aes_key_random_mode(); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); +} +#endif + +TEST_GROUP(key_manager); + +TEST_SETUP(key_manager) +{ + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(700, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); +} + +TEST_TEAR_DOWN(key_manager) +{ + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +TEST(key_manager, xts_aes_128_key_aes_deployment) +{ + key_mgr_test_xts_aes_128(); +} + +TEST(key_manager, xts_aes_256_key_aes_deployment) +{ + key_mgr_test_xts_aes_256_aes_mode(); +} + +TEST(key_manager, ecdsa_key_aes_deployment) +{ + key_mgr_test_ecdsa_p256_aes_mode(); +} + +TEST(key_manager, xts_key_ecdh0_deployment) +{ + key_mgr_test_xts_aes_128_ecdh0_mode(); + key_mgr_test_xts_aes_256_ecdh0_mode(); +} + +TEST(key_manager, ecdsa_key_ecdh0_deployment) +{ + key_mgr_test_ecdsa_ecdh0_mode(); +} + +TEST(key_manager, ecdsa_key_random_deployment) +{ + key_mgr_test_ecdsa_random_mode(); +} + +#if CONFIG_IDF_ENV_FPGA +TEST(key_manager, xts_key_random_deployment) +{ + key_mgr_test_xts_aes_128_random_mode(); + key_mgr_test_xts_aes_256_random_mode(); +} +#endif + +TEST_GROUP_RUNNER(key_manager) +{ + RUN_TEST_CASE(key_manager, xts_aes_128_key_aes_deployment); + RUN_TEST_CASE(key_manager, xts_aes_256_key_aes_deployment); + RUN_TEST_CASE(key_manager, ecdsa_key_aes_deployment); + RUN_TEST_CASE(key_manager, xts_key_ecdh0_deployment); + RUN_TEST_CASE(key_manager, ecdsa_key_ecdh0_deployment); + RUN_TEST_CASE(key_manager, ecdsa_key_random_deployment); +#if CONFIG_IDF_ENV_FPGA + RUN_TEST_CASE(key_manager, xts_key_random_deployment); +#endif + +} diff --git a/components/hal/test_apps/crypto/pytest_crypto.py b/components/hal/test_apps/crypto/pytest_crypto.py index d988e8eb6d5..64fe21473b4 100644 --- a/components/hal/test_apps/crypto/pytest_crypto.py +++ b/components/hal/test_apps/crypto/pytest_crypto.py @@ -1,18 +1,159 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 +import binascii import os +import subprocess +from typing import Any import pytest +from cryptography import exceptions +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric import utils +from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1 +from cryptography.hazmat.primitives.serialization import load_pem_private_key +from ecdsa import NIST256p +from ecdsa.ellipticcurve import Point from pytest_embedded import Dut +def load_ecdsa_key(filename: str) -> SECP256R1: + with open(filename, 'rb') as key_file: + return load_pem_private_key(key_file.read(), password=None, backend=default_backend()) + + +def test_xts_aes_encryption(negotiated_key: bytes, plaintext_data: bytes, encrypted_data: bytes) -> None: + with open('test/negotiated_key.bin', 'wb+') as key_file: + key_file.write(negotiated_key) + + with open('test/plaintext.bin', 'wb+') as plaintext_file: + plaintext_file.write(plaintext_data) + + command = [ + 'espsecure.py', + 'encrypt_flash_data', + '--aes_xts', + '--keyfile', 'test/negotiated_key.bin', + '--address', '0x120000', + '--output', 'test/enc-data.bin', + 'test/plaintext.bin' + ] + result = subprocess.run(command, capture_output=True, text=True) + assert result.returncode == 0, f'Command failed with error: {result.stderr}' + + with open('test/enc-data.bin', 'rb') as enc_file: + calculated_enc_data = enc_file.read() + + assert calculated_enc_data == encrypted_data, 'Calculated data does not match encrypted data obtained from firmware' + + +def calculate_key_manager_ecdh0_negotiated_key(k2_G_hex: str, k1_ecdsa_key: str) -> Any: + k2_G_bytes_le = binascii.unhexlify(k2_G_hex) + + k2_G_bytes_x_be = bytes(reversed(k2_G_bytes_le[:32])) + k2_G_bytes_y_be = bytes(reversed(k2_G_bytes_le[32:])) + + k2_G_bytes_be = k2_G_bytes_x_be + k2_G_bytes_y_be + + curve = NIST256p.curve + k2_G = Point.from_bytes(curve, k2_G_bytes_be) + + # Load the ECDSA private key (k1) + k1_key = load_ecdsa_key(k1_ecdsa_key) + k1_int = k1_key.private_numbers().private_value + + # Convert the integer to bytes in big endian format + k1_bytes_big_endian = k1_int.to_bytes((k1_int.bit_length() + 7) // 8, byteorder='big') + + # Reverse the bytes to get little endian format + k1_bytes_little_endian = k1_bytes_big_endian[::-1] + + k1_int = int.from_bytes(k1_bytes_little_endian, byteorder='little') + + # Calculate k1*k2*G + k1_k2_G = k1_int * k2_G + + # Extract the x-coordinate of the result and save it as the shared secret + negotiated_key = k1_k2_G.to_bytes()[:32] + return negotiated_key + + +def test_ecdsa_key(negotiated_key: bytes, digest: bytes, signature_r_le: bytes, signature_s_le: bytes, pubx: bytes, puby: bytes) -> None: + r = int.from_bytes(signature_r_le, 'little') + s = int.from_bytes(signature_s_le, 'little') + signature = utils.encode_dss_signature(r, s) + pubx_int = int.from_bytes(pubx, 'little') + puby_int = int.from_bytes(puby, 'little') + private_number = int.from_bytes(negotiated_key, byteorder='big') + ecdsa_private_key = ec.derive_private_key(private_number, ec.SECP256R1()) + # Get the public key + public_key = ecdsa_private_key.public_key() + # Extract the pubx and puby values + calc_pubx, calc_puby = public_key.public_numbers().x, public_key.public_numbers().y + + assert calc_pubx == pubx_int, 'Public key calculated should match with public key obtained' + assert calc_puby == puby_int, 'Public key calculated should match with public key obtained' + + try: + public_key.verify(signature, digest, ec.ECDSA(utils.Prehashed(hashes.SHA256()))) + print('Valid signature') + except exceptions.InvalidSignature: + print('Invalid signature') + raise + + @pytest.mark.supported_targets @pytest.mark.generic def test_crypto(dut: Dut) -> None: # if the env variable IDF_FPGA_ENV is set, we would need a longer timeout # as tests for efuses burning security peripherals would be run timeout = 600 if os.environ.get('IDF_ENV_FPGA') else 60 + # only expect key manager result if it is supported for the SoC + if dut.app.sdkconfig.get('SOC_KEY_MANAGER_SUPPORTED'): + print('Key Manager is supported') + + # Test for ECDH0 deployment XTS-AES-128 key + dut.expect('Key Manager ECDH0 deployment: XTS_AES_128 key', timeout=timeout) + k2_G = dut.expect(r'K2_G: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + plaintext_data = dut.expect(r'Plaintext data: 0x([0-9a-fA-F]+)', timeout=timeout)[1] + plaintext_data = binascii.unhexlify(plaintext_data) + encrypted_data = dut.expect(r'Encrypted data: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + encrypted_data = binascii.unhexlify(encrypted_data) + negotiated_key = calculate_key_manager_ecdh0_negotiated_key(k2_G, 'main/key_manager/k1_ecdsa.pem') + test_xts_aes_encryption(negotiated_key, plaintext_data, encrypted_data) + + # Test for ECDH0 deployment XTS-AES-256 key + dut.expect('Key Manager ECDH0 deployment: XTS_AES_256 key', timeout=timeout) + k2_G_0 = dut.expect(r'K2_G_0: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + k2_G_1 = dut.expect(r'K2_G_1: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + encrypted_data = dut.expect(r'Encrypted data: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + encrypted_data = binascii.unhexlify(encrypted_data) + negotiated_key_0 = calculate_key_manager_ecdh0_negotiated_key(k2_G_0, 'main/key_manager/k1_ecdsa.pem') + negotiated_key_1 = calculate_key_manager_ecdh0_negotiated_key(k2_G_1, 'main/key_manager/k1_ecdsa.pem') + negotiated_key = negotiated_key_0 + negotiated_key_1 + test_xts_aes_encryption(negotiated_key, plaintext_data, encrypted_data) + # Test for ECDH0 deployment ECDSA-256 key + dut.expect('Key Manager ECDH0 deployment: ECDSA_256 key', timeout=timeout) + k2_G = dut.expect(r'K2_G: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + digest = dut.expect(r'ECDSA message sha256 digest: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + digest = binascii.unhexlify(digest) + signature_r_le = dut.expect(r'ECDSA signature r_le: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + signature_r_le = binascii.unhexlify(signature_r_le) + signature_s_le = dut.expect(r'ECDSA signature s_le: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + signature_s_le = binascii.unhexlify(signature_s_le) + pub_x = dut.expect(r'ECDSA key pubx: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + pub_x = binascii.unhexlify(pub_x) + pub_y = dut.expect(r'ECDSA key puby: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode() + pub_y = binascii.unhexlify(pub_y) + negotiated_key = calculate_key_manager_ecdh0_negotiated_key(k2_G, 'main/key_manager/k1_ecdsa.pem') + test_ecdsa_key(negotiated_key, digest, signature_r_le, signature_s_le, pub_x, pub_y) + test_numbers = dut.expect(r'(\d+) Tests (\d+) Failures (\d+) Ignored', timeout=timeout) + failures = test_numbers.group(2).decode() + ignored = test_numbers.group(3).decode() + assert failures == '0', f'No of failures must be 0 (is {failures})' + assert ignored == '0', f'No of Ignored test must be 0 (is {ignored})' dut.expect('Tests finished', timeout=timeout) diff --git a/components/heap/test_apps/.build-test-rules.yml b/components/heap/test_apps/.build-test-rules.yml index a55adfc1764..1e3b8ecd8cf 100644 --- a/components/heap/test_apps/.build-test-rules.yml +++ b/components/heap/test_apps/.build-test-rules.yml @@ -3,9 +3,6 @@ components/heap/test_apps/heap_tests: disable: - if: IDF_TARGET == "linux" - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: not support yet # TODO: [ESP32C5] IDF-9641 - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 # These 3 configs are build only for non-nightly, buildig for a single target is sufficient diff --git a/components/heap/test_apps/heap_tests/README.md b/components/heap/test_apps/heap_tests/README.md index 5b39ff96532..b8fe0d892df 100644 --- a/components/heap/test_apps/heap_tests/README.md +++ b/components/heap/test_apps/heap_tests/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 44858861535..f45eeab2ed1 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -207,10 +207,6 @@ if(CONFIG_LWIP_ENABLE) idf_component_optional_requires(PRIVATE openthread) endif() - if(CONFIG_ETH_ENABLED) - idf_component_optional_requires(PRIVATE esp_eth) - endif() - if(CONFIG_LWIP_DHCP_RESTORE_LAST_IP) idf_component_optional_requires(PRIVATE nvs_flash) endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 67cf8cc483f..0f4b84eb97f 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -744,21 +744,21 @@ menu "mbedTLS" depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C && MBEDTLS_ECDSA_C default y help - Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH- + Enable to support ciphersuites with prefix TLS-ECDHE-ECDSA-WITH- config MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA bool "Enable ECDH-ECDSA based ciphersuite modes" depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C && MBEDTLS_ECDSA_C default y help - Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH- + Enable to support ciphersuites with prefix TLS-ECDH-ECDSA-WITH- config MBEDTLS_KEY_EXCHANGE_ECDH_RSA bool "Enable ECDH-RSA based ciphersuite modes" depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C default y help - Enable to support ciphersuites with prefix TLS-ECDHE-RSA-WITH- + Enable to support ciphersuites with prefix TLS-ECDH-RSA-WITH- config MBEDTLS_KEY_EXCHANGE_ECJPAKE bool "Enable ECJPAKE based ciphersuite modes" diff --git a/components/newlib/test_apps/.build-test-rules.yml b/components/newlib/test_apps/.build-test-rules.yml index e2345cd62b7..fcc2d44faf3 100644 --- a/components/newlib/test_apps/.build-test-rules.yml +++ b/components/newlib/test_apps/.build-test-rules.yml @@ -4,4 +4,4 @@ components/newlib/test_apps/newlib: disable: - if: IDF_TARGET == "esp32c5" temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8675 + reason: not supported yet # TODO: [ESP32C5] IDF-8675, IDF-10312 diff --git a/components/newlib/test_apps/newlib/pytest_newlib.py b/components/newlib/test_apps/newlib/pytest_newlib.py index 4569c93f081..3d59ed842f4 100644 --- a/components/newlib/test_apps/newlib/pytest_newlib.py +++ b/components/newlib/test_apps/newlib/pytest_newlib.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import subprocess from os import path @@ -32,6 +31,7 @@ def validate_sbom(dut: Dut) -> None: @pytest.mark.generic +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not support yet') # TODO: [ESP32C5] IDF-8675, IDF-10312 @pytest.mark.parametrize( 'config', [ diff --git a/components/nvs_flash/test_nvs_host/Makefile b/components/nvs_flash/test_nvs_host/Makefile index 7e8659aebf8..e1849a6cb9c 100644 --- a/components/nvs_flash/test_nvs_host/Makefile +++ b/components/nvs_flash/test_nvs_host/Makefile @@ -34,7 +34,7 @@ else COMPILER := gcc endif -CPPFLAGS += -I../private_include -I../include -I../src -I../../heap/include -I../../esp_rom/include -I../../esp_rom/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../esp_partition/include -I ../../hal/include -I ../../xtensa/include -I ../../soc/linux/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb +CPPFLAGS += -I../private_include -I../include -I../src -I../../heap/include -I../../esp_rom/include -I../../esp_rom/include/linux -I../../esp_rom/linux/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../esp_partition/include -I ../../hal/include -I ../../xtensa/include -I ../../soc/linux/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb CFLAGS += -fprofile-arcs -ftest-coverage -DLINUX_TARGET -DLINUX_HOST_LEGACY_TEST CXXFLAGS += -std=c++11 -Wall -Werror -DLINUX_TARGET -DLINUX_HOST_LEGACY_TEST LDFLAGS += -lstdc++ -Wall -fprofile-arcs -ftest-coverage diff --git a/components/pthread/pthread_local_storage.c b/components/pthread/pthread_local_storage.c index 19cb73a98d8..80b562edb53 100644 --- a/components/pthread/pthread_local_storage.c +++ b/components/pthread/pthread_local_storage.c @@ -147,7 +147,9 @@ static void pthread_cleanup_thread_specific_data_callback(int index, void *v_tls free(tls); } -/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread */ +/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread + and from pthread_join/pthread_detach for cleanup of TLS after pthread exit +*/ void pthread_internal_local_storage_destructor_callback(TaskHandle_t handle) { void *tls = pvTaskGetThreadLocalStoragePointer(handle, PTHREAD_TLS_INDEX); @@ -157,9 +159,9 @@ void pthread_internal_local_storage_destructor_callback(TaskHandle_t handle) calling it again... */ #if !defined(CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS) - vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, NULL); + vTaskSetThreadLocalStoragePointer(handle, PTHREAD_TLS_INDEX, NULL); #else - vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, + vTaskSetThreadLocalStoragePointerAndDelCallback(handle, PTHREAD_TLS_INDEX, NULL, NULL); diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index a9d6abc8e66..bb9456119d8 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -131,6 +131,10 @@ config SOC_SECURE_BOOT_SUPPORTED bool default y +config SOC_PMU_SUPPORTED + bool + default y + config SOC_LP_TIMER_SUPPORTED bool default y @@ -139,6 +143,14 @@ config SOC_LP_PERIPHERALS_SUPPORTED bool default y +config SOC_CLK_TREE_SUPPORTED + bool + default y + +config SOC_WDT_SUPPORTED + bool + default y + config SOC_SPI_FLASH_SUPPORTED bool default y @@ -235,6 +247,10 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP bool default y +config SOC_CPU_PMP_REGION_GRANULARITY + int + default 128 + config SOC_DS_SIGNATURE_MAX_BIT_LEN int default 3072 @@ -279,6 +295,14 @@ config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y +config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + bool + default y + +config SOC_LP_IO_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_GPIO_IN_RANGE_MAX int default 28 @@ -309,7 +333,19 @@ config SOC_GPIO_CLOCKOUT_CHANNEL_NUM config SOC_RTCIO_PIN_COUNT int - default 0 + default 8 + +config SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + bool + default y + +config SOC_RTCIO_HOLD_SUPPORTED + bool + default y + +config SOC_RTCIO_WAKE_SUPPORTED + bool + default y config SOC_I2C_NUM int @@ -479,6 +515,10 @@ config SOC_PCNT_SUPPORT_CLEAR_SIGNAL bool default y +config SOC_PCNT_SUPPORT_STEP_NOTIFY + bool + default y + config SOC_RMT_GROUPS int default 1 @@ -823,6 +863,10 @@ config SOC_FLASH_ENCRYPTION_XTS_AES_128 bool default y +config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED + bool + default y + config SOC_UART_NUM int default 3 @@ -847,6 +891,14 @@ config SOC_UART_BITRATE_MAX int default 5000000 +config SOC_UART_SUPPORT_PLL_F80M_CLK + bool + default y + +config SOC_UART_SUPPORT_RTC_CLK + bool + default y + config SOC_UART_SUPPORT_XTAL_CLK bool default y @@ -895,6 +947,10 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD bool default y +config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION + bool + default y + config SOC_MODEM_CLOCK_IS_INDEPENDENT bool default y @@ -911,6 +967,10 @@ config SOC_CLK_RC32K_SUPPORTED bool default y +config SOC_CLK_LP_FAST_SUPPORT_XTAL + bool + default y + config SOC_RCC_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32c5/include/soc/clk_tree_defs.h b/components/soc/esp32c5/include/soc/clk_tree_defs.h index ee7437c0e57..f777e097155 100644 --- a/components/soc/esp32c5/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/include/soc/clk_tree_defs.h @@ -19,7 +19,7 @@ extern "C" { * * The exact frequency of RC_FAST_CLK can be computed in runtime through calibration. * - * 2) External 40/48MHz Crystal Clock: XTAL + * 2) External 48MHz Crystal Clock: XTAL * * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) * @@ -45,7 +45,6 @@ extern "C" { * OSC_SLOW_CLK can also be calibrated to get its exact frequency. */ -// TODO: [ESP32C5] IDF-8642 (inherit from C6) /* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */ #define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */ #define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */ @@ -60,10 +59,10 @@ extern "C" { /** * @brief Root clock */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */ SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */ - SOC_ROOT_CLK_EXT_XTAL, /*!< External 40MHz crystal */ + SOC_ROOT_CLK_EXT_XTAL, /*!< External 48MHz crystal */ SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */ SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */ SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0 */ @@ -73,12 +72,11 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief CPU_CLK mux inputs, which are the supported clock sources for the CPU_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */ SOC_CPU_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as CPU_CLK source */ SOC_CPU_CLK_SRC_PLL_F160M = 2, /*!< Select PLL_F160M_CLK as CPU_CLK source (PLL_F160M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ SOC_CPU_CLK_SRC_PLL_F240M = 3, /*!< Select PLL_F240M_CLK as CPU_CLK source (PLL_F240M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ - SOC_CPU_CLK_SRC_PLL = SOC_CPU_CLK_SRC_PLL_F240M, // TODO: [IDF-8642] remove this alias SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */ } soc_cpu_clk_src_t; @@ -86,7 +84,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief RTC_SLOW_CLK mux inputs, which are the supported clock sources for the RTC_SLOW_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ @@ -98,7 +96,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief RTC_FAST_CLK mux inputs, which are the supported clock sources for the RTC_FAST_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */ @@ -125,7 +123,7 @@ typedef enum { * * @note enum starts from 1, to save 0 for special purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { // For CPU domain SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, or RC_FAST by configuring soc_cpu_clk_src_t */ // For RTC domain @@ -138,9 +136,9 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */ SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */ - SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */ + SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 48MHz crystal */ // For LP peripherals - SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */ + SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 48MHz crystal, passing a div of 2 to the LP peripherals */ SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */ } soc_module_clk_t; @@ -170,11 +168,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8676 (inherit from C6) * } * @endcode */ -#if SOC_CLK_TREE_SUPPORTED #define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL} -#else -#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL} -#endif /** * @brief Type of GPTimer clock source @@ -183,11 +177,7 @@ typedef enum { GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */ GPTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ -#if SOC_CLK_TREE_SUPPORTED GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */ -#else - GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */ -#endif // SOC_CLK_TREE_SUPPORTED } soc_periph_gptimer_clk_src_t; /** @@ -196,11 +186,7 @@ typedef enum { typedef enum { TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source is PLL_F80M */ TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */ -#if SOC_CLK_TREE_SUPPORTED TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source default choice is PLL_F80M */ -#else - TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Timer group clock source default choice is XTAL */ -#endif // SOC_CLK_TREE_SUPPORTED } soc_periph_tg_clk_src_legacy_t; //////////////////////////////////////////////////RMT/////////////////////////////////////////////////////////////////// @@ -259,11 +245,7 @@ typedef enum { UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */ UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */ UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */ -#if SOC_CLK_TREE_SUPPORTED UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */ -#else - UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment*/ -#endif } soc_periph_uart_clk_src_legacy_t; /** @@ -295,11 +277,7 @@ typedef enum { typedef enum { MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ -#if SOC_CLK_TREE_SUPPORTED MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ -#else - MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ -#endif } soc_periph_mcpwm_timer_clk_src_t; /** @@ -313,11 +291,7 @@ typedef enum { typedef enum { MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ -#if SOC_CLK_TREE_SUPPORTED MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ -#else - MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ -#endif } soc_periph_mcpwm_capture_clk_src_t; /** @@ -331,11 +305,7 @@ typedef enum { typedef enum { MCPWM_CARRIER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ -#if SOC_CLK_TREE_SUPPORTED MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */ -#else - MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ -#endif } soc_periph_mcpwm_carrier_clk_src_t; ///////////////////////////////////////////////////// I2S ////////////////////////////////////////////////////////////// @@ -402,11 +372,7 @@ typedef enum { SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */ SPI_CLK_SRC_PLL_F160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as SPI source clock */ SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */ -#if SOC_CLK_TREE_SUPPORTED SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_80M as SPI source clock */ -#else - SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select PLL_80M as SPI source clock */ -#endif } soc_periph_spi_clk_src_t; //////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// @@ -484,11 +450,11 @@ typedef enum { // TODO: [ESP32C5] IDF-8701, IDF-8702, IDF-8703 (inherit from C6 /** * @brief MWDT clock source */ -typedef enum { // TODO: [ESP32C5] IDF-8650 (inherit from C6) +typedef enum { MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ MWDT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the source clock */ MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */ - MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select PLL fixed 80 MHz as the default clock choice */ + MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL fixed 48 MHz as the default clock choice */ } soc_periph_mwdt_clk_src_t; //////////////////////////////////////////////////LEDC///////////////////////////////////////////////////////////////// @@ -525,11 +491,7 @@ typedef enum { PARLIO_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ PARLIO_CLK_SRC_PLL_F240M = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as the source clock */ PARLIO_CLK_SRC_EXTERNAL = -1, /*!< Select EXTERNAL clock as the source clock */ -#if SOC_CLK_TREE_SUPPORTED // TODO: [ESP32C5] IDF-8642 remove when clock tree is supported PARLIO_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as the default clock choice */ -#else - PARLIO_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ -#endif } soc_periph_parlio_clk_src_t; //////////////////////////////////////////////////MSPI/////////////////////////////////////////////////////////////////// @@ -548,7 +510,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8649 } soc_periph_mspi_clk_src_t; //////////////////////////////////////////////CLOCK OUTPUT/////////////////////////////////////////////////////////// -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { // TODO CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */ CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */ CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */ diff --git a/components/soc/esp32c5/include/soc/pcr_reg.h b/components/soc/esp32c5/include/soc/pcr_reg.h index b8e084f1a74..e9e7316b2a6 100644 --- a/components/soc/esp32c5/include/soc/pcr_reg.h +++ b/components/soc/esp32c5/include/soc/pcr_reg.h @@ -1902,21 +1902,6 @@ extern "C" { * SYSCLK configuration register */ #define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x110) -/** PCR_LS_DIV_NUM : HRO; bitpos: [7:0]; default: 0; - * clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed - * clock-source such as XTAL/FOSC. - */ -#define PCR_LS_DIV_NUM 0x000000FFU -#define PCR_LS_DIV_NUM_M (PCR_LS_DIV_NUM_V << PCR_LS_DIV_NUM_S) -#define PCR_LS_DIV_NUM_V 0x000000FFU -#define PCR_LS_DIV_NUM_S 0 -/** PCR_HS_DIV_NUM : HRO; bitpos: [15:8]; default: 2; - * clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL. - */ -#define PCR_HS_DIV_NUM 0x000000FFU -#define PCR_HS_DIV_NUM_M (PCR_HS_DIV_NUM_V << PCR_HS_DIV_NUM_S) -#define PCR_HS_DIV_NUM_V 0x000000FFU -#define PCR_HS_DIV_NUM_S 8 /** PCR_SOC_CLK_SEL : R/W; bitpos: [17:16]; default: 0; * Configures to select the clock source of HP_ROOT_CLK.\\ * 0 (default): XTAL_CLK\\ diff --git a/components/soc/esp32c5/include/soc/pcr_struct.h b/components/soc/esp32c5/include/soc/pcr_struct.h index db621a0671e..15acd48aad6 100644 --- a/components/soc/esp32c5/include/soc/pcr_struct.h +++ b/components/soc/esp32c5/include/soc/pcr_struct.h @@ -1642,15 +1642,7 @@ typedef union { */ typedef union { struct { - /** ls_div_num : HRO; bitpos: [7:0]; default: 0; - * clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed - * clock-source such as XTAL/FOSC. - */ - uint32_t ls_div_num:8; - /** hs_div_num : HRO; bitpos: [15:8]; default: 2; - * clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL. - */ - uint32_t hs_div_num:8; + uint32_t reserved_0:16; /** soc_clk_sel : R/W; bitpos: [17:16]; default: 0; * Configures to select the clock source of HP_ROOT_CLK.\\ * 0 (default): XTAL_CLK\\ @@ -1706,7 +1698,7 @@ typedef union { typedef union { struct { /** cpu_div_num : R/W; bitpos: [7:0]; default: 0; - * Set this field to generate clk_cpu driven by clk_hproot. The clk_cpu is + * Set this field to generate clk_cpu derived by clk_hproot. The clk_cpu is * div1(default)/div2/div4 of clk_hproot. This field is only available for low-speed * clock-source such as XTAL/FOSC, and should be used together with PCR_AHB_DIV_NUM. */ @@ -1722,7 +1714,7 @@ typedef union { typedef union { struct { /** ahb_div_num : R/W; bitpos: [7:0]; default: 0; - * Set this field to generate clk_ahb driven by clk_hproot. The clk_ahb is + * Set this field to generate clk_ahb derived by clk_hproot. The clk_ahb is * div1(default)/div2/div4/div8 of clk_hproot. This field is only available for * low-speed clock-source such as XTAL/FOSC, and should be used together with * PCR_CPU_DIV_NUM. @@ -1749,7 +1741,7 @@ typedef union { */ uint32_t apb_decrease_div_num:8; /** apb_div_num : R/W; bitpos: [15:8]; default: 0; - * Set as one within (0,1,3) to generate clk_apb driven by clk_ahb. The clk_apb is + * Set as one within (0,1,3) to generate clk_apb derived by clk_ahb. The clk_apb is * div1(default)/div2/div4 of clk_ahb. */ uint32_t apb_div_num:8; @@ -1764,47 +1756,47 @@ typedef union { typedef union { struct { /** pll_240m_clk_en : R/W; bitpos: [0]; default: 1; - * This field is used to open 240 MHz clock (div2 of SPLL) driven from SPLL. 0: close, + * This field is used to open 240 MHz clock (div2 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_240m_clk_en:1; /** pll_160m_clk_en : R/W; bitpos: [1]; default: 1; - * This field is used to open 160 MHz clock (div3 of SPLL) driven from SPLL. 0: close, + * This field is used to open 160 MHz clock (div3 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_160m_clk_en:1; /** pll_120m_clk_en : R/W; bitpos: [2]; default: 1; - * This field is used to open 120 MHz clock (div4 of SPLL) driven from SPLL. 0: close, + * This field is used to open 120 MHz clock (div4 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_120m_clk_en:1; /** pll_80m_clk_en : R/W; bitpos: [3]; default: 1; - * This field is used to open 80 MHz clock (div6 of SPLL) driven from SPLL. 0: close, + * This field is used to open 80 MHz clock (div6 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_80m_clk_en:1; /** pll_60m_clk_en : R/W; bitpos: [4]; default: 1; - * This field is used to open 60 MHz clock (div8 of SPLL) driven from SPLL. 0: close, + * This field is used to open 60 MHz clock (div8 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_60m_clk_en:1; /** pll_48m_clk_en : R/W; bitpos: [5]; default: 1; - * This field is used to open 48 MHz clock (div10 of SPLL) driven from SPLL. 0: close, + * This field is used to open 48 MHz clock (div10 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_48m_clk_en:1; /** pll_40m_clk_en : R/W; bitpos: [6]; default: 1; - * This field is used to open 40 MHz clock (div12 of SPLL) driven from SPLL. 0: close, + * This field is used to open 40 MHz clock (div12 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_40m_clk_en:1; /** pll_20m_clk_en : R/W; bitpos: [7]; default: 1; - * This field is used to open 20 MHz clock (div24 of SPLL) driven from SPLL. 0: close, + * This field is used to open 20 MHz clock (div24 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_20m_clk_en:1; /** pll_12m_clk_en : R/W; bitpos: [8]; default: 1; - * This field is used to open 12 MHz clock (div40 of SPLL) driven from SPLL. 0: close, + * This field is used to open 12 MHz clock (div40 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_12m_clk_en:1; diff --git a/components/soc/esp32c5/include/soc/rmt_struct.h b/components/soc/esp32c5/include/soc/rmt_struct.h index 124bc72bff5..af0acf14329 100644 --- a/components/soc/esp32c5/include/soc/rmt_struct.h +++ b/components/soc/esp32c5/include/soc/rmt_struct.h @@ -827,7 +827,7 @@ typedef struct rmt_dev_t { volatile struct { rmt_chmconf0_reg_t conf0; rmt_chmconf1_reg_t conf1; - } chmconf[2];; + } chmconf[2]; volatile rmt_chnstatus_reg_t chnstatus[2]; volatile rmt_chmstatus_reg_t chmstatus[2]; volatile rmt_int_raw_reg_t int_raw; diff --git a/components/soc/esp32c5/include/soc/rtc_io_channel.h b/components/soc/esp32c5/include/soc/rtc_io_channel.h new file mode 100644 index 00000000000..df2120f045b --- /dev/null +++ b/components/soc/esp32c5/include/soc/rtc_io_channel.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define RTCIO_GPIO0_CHANNEL 0 //RTCIO_CHANNEL_0 +#define RTCIO_CHANNEL_0_GPIO_NUM 0 + +#define RTCIO_GPIO1_CHANNEL 1 //RTCIO_CHANNEL_1 +#define RTCIO_CHANNEL_1_GPIO_NUM 1 + +#define RTCIO_GPIO2_CHANNEL 2 //RTCIO_CHANNEL_2 +#define RTCIO_CHANNEL_2_GPIO_NUM 2 + +#define RTCIO_GPIO3_CHANNEL 3 //RTCIO_CHANNEL_3 +#define RTCIO_CHANNEL_3_GPIO_NUM 3 + +#define RTCIO_GPIO4_CHANNEL 4 //RTCIO_CHANNEL_4 +#define RTCIO_CHANNEL_4_GPIO_NUM 4 + +#define RTCIO_GPIO5_CHANNEL 5 //RTCIO_CHANNEL_5 +#define RTCIO_CHANNEL_5_GPIO_NUM 5 + +#define RTCIO_GPIO6_CHANNEL 6 //RTCIO_CHANNEL_6 +#define RTCIO_CHANNEL_6_GPIO_NUM 6 + +#define RTCIO_GPIO7_CHANNEL 7 //RTCIO_CHANNEL_7 +#define RTCIO_CHANNEL_7_GPIO_NUM 7 diff --git a/components/soc/esp32c5/include/soc/soc.h b/components/soc/esp32c5/include/soc/soc.h index 8185b1fccc2..7f4536f0d8a 100644 --- a/components/soc/esp32c5/include/soc/soc.h +++ b/components/soc/esp32c5/include/soc/soc.h @@ -154,9 +154,9 @@ #define SOC_DROM_LOW SOC_IROM_LOW #define SOC_DROM_HIGH SOC_IROM_HIGH #define SOC_IROM_MASK_LOW 0x40000000 -#define SOC_IROM_MASK_HIGH 0x40040000 +#define SOC_IROM_MASK_HIGH 0x40050000 #define SOC_DROM_MASK_LOW 0x40000000 -#define SOC_DROM_MASK_HIGH 0x40040000 +#define SOC_DROM_MASK_HIGH 0x40050000 #define SOC_IRAM_LOW 0x40800000 #define SOC_IRAM_HIGH 0x40860000 #define SOC_DRAM_LOW 0x40800000 @@ -198,9 +198,9 @@ #define SOC_PERIPHERAL_LOW 0x60000000 #define SOC_PERIPHERAL_HIGH 0x60100000 -// Debug region, not used by software -#define SOC_DEBUG_LOW 0x20000000 -#define SOC_DEBUG_HIGH 0x28000000 +// CPU sub-system region, contains interrupt config registers +#define SOC_CPU_SUBSYSTEM_LOW 0x20000000 +#define SOC_CPU_SUBSYSTEM_HIGH 0x30000000 // Start (highest address) of ROM boot stack, only relevant during early boot #define SOC_ROM_STACK_START 0x4085e9a0 diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index 155000b197b..1acf26f6d6b 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -58,21 +58,23 @@ #define SOC_SECURE_BOOT_SUPPORTED 1 // #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647 // #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614, IDF-8615 -// #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 +#define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 // #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_LP_TIMER_SUPPORTED 1 // #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_LP_PERIPHERALS_SUPPORTED 1 // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634 // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633 -// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32C5] IDF-8642 +#define SOC_CLK_TREE_SUPPORTED 1 // #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32C5] IDF-8663 -// #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650 +#define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715 // #define SOC_BITSCRAMBLER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8711 #define SOC_ECDSA_SUPPORTED 1 // #define SOC_KEY_MANAGER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8621 // #define SOC_HUK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8617 +// #define SOC_LIGHT_SLEEP_SUPPORTED 1 // TODO: [ESP32C5] IDF-8640 +// #define SOC_DEEP_SLEEP_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_MODEM_CLOCK_SUPPORTED 1 // #define SOC_PM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8643 @@ -154,6 +156,7 @@ #define SOC_CPU_HAS_PMA 1 #define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 +#define SOC_CPU_PMP_REGION_GRANULARITY 128 /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /** The maximum length of a Digital Signature in bits. */ @@ -195,7 +198,9 @@ // On ESP32-C5, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) // GPIO0~7 on ESP32C5 can support chip deep sleep wakeup -// #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) // TODO: [ESP32C5] IDF-8719 +#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) +// LP IO peripherals have independent clock gating to manage +#define SOC_LP_IO_CLOCK_IS_INDEPENDENT (1) #define SOC_GPIO_VALID_GPIO_MASK ((1U< +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LP SPI peripheral + * Since we have just one LP SPI peripheral, we can define it as a uint32_t type for now, instead of an enum. + */ +typedef uint32_t lp_spi_host_t; + +/** + * @brief LP SPI device configuration flags + */ +#define LP_SPI_DEVICE_TXBIT_LSBFIRST (1<<0) /*!< Transmit command/address/data LSB first instead of the default MSB first */ +#define LP_SPI_DEVICE_RXBIT_LSBFIRST (1<<1) /*!< Receive data LSB first instead of the default MSB first */ +#define LP_SPI_DEVICE_BIT_LSBFIRST (LP_SPI_DEVICE_TXBIT_LSBFIRST|LP_SPI_DEVICE_RXBIT_LSBFIRST) /*!< Transmit and receive LSB first */ +#define LP_SPI_DEVICE_3WIRE (1<<2) /*!< Use MOSI (=spid) for both sending and receiving data */ +#define LP_SPI_DEVICE_CS_ACTIVE_HIGH (1<<3) /*!< Make CS line active-high during a transanction instead of the default active-low state. Only available in SPI master mode. */ +#define LP_SPI_DEVICE_HALF_DUPLEX (1<<4) /*!< Transmit data before receiving it, instead of simultaneously. Only available in SPI master mode. */ + +/** + * @brief LP SPI bus configuration parameters + */ +typedef struct { + int mosi_io_num; /*!< GPIO pin for Master out, Slave In signal, a.k.a, SPI_D. */ + int miso_io_num; /*!< GPIO pin for Master in, Slave Out signal, a.k.a, SPI_Q. */ + int sclk_io_num; /*!< GPIO pin for LP SPI Clock signal. */ +} lp_spi_bus_config_t; + +/** + * @brief LP SPI device configuration parameters + */ +typedef struct { + int cs_io_num; /*!< GPIO pin for the device Chip Select (CS) signal. */ + int clock_speed_hz; /*!< SPI clock speed in Hz. */ + int spi_mode; /*!< SPI mode, representing a pair of Clock Polarity (CPOL) and Clock Phase (CPHA) configuration: + - SPI Mode 0: (0, 0) + - SPI Mode 1: (0, 1) + - SPI Mode 2: (1, 0) + - SPI Mode 3: (1, 1) + */ + int duty_cycle; /*!< Duty cycle of positive SPI clock, in 1/256th increments (128 = 50% duty cycle). Setting this to 0 (=not setting it) is equivalent to setting this to 128. */ + int flags; /*!< Bitwise OR of LP_SPI_DEVICE_* flags */ + int cs_ena_pretrans; /*!< Amount of SPI bit-cycles the CS should be active for, before the transmission (0-16). This only works on half-duplex transactions. */ + int cs_ena_posttrans; /*!< Amount of SPI bit-cycles the CS should stay active for, after the transmission (0-16). This only works on half-duplex transactions. */ +} lp_spi_device_config_t; + +/** + * @brief LP SPI slave configuration parameters + */ +typedef struct { + int cs_io_num; /*!< GPIO pin for the device Chip Select (CS) signal. */ + int spi_mode; /*!< SPI mode, representing a pair of Clock Polarity (CPOL) and Clock Phase (CPHA) configuration: + - SPI Mode 0: (0, 0) + - SPI Mode 1: (0, 1) + - SPI Mode 2: (1, 0) + - SPI Mode 3: (1, 1) + */ + int flags; /*!< Bitwise OR of LP_SPI_DEVICE_* flags */ +} lp_spi_slave_config_t; + +/** + * @brief Initialize the LP SPI bus for use by the LP core + * + * @param host_id LP SPI host number + * @param bus_config LP SPI bus configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + */ +esp_err_t lp_core_lp_spi_bus_initialize(lp_spi_host_t host_id, const lp_spi_bus_config_t *bus_config); + +/** + * @brief Initialize the LP SPI controller in master mode and add an SPI device to the LP SPI bus. + * + * @param host_id LP SPI host number + * @param dev_config LP SPI device configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_FAIL if the device could not be added + */ +esp_err_t lp_core_lp_spi_bus_add_device(lp_spi_host_t host_id, const lp_spi_device_config_t *dev_config); + +/** + * @brief Initialize the LP SPI controller in slave mode + * + * @param host_id LP SPI host number + * @param slave_config LP SPI slave configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_FAIL if the SPI controller could not be initialized in slave mode + */ +esp_err_t lp_core_lp_spi_slave_initialize(lp_spi_host_t host_id, const lp_spi_slave_config_t *slave_config); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/include/ulp_lp_core.h b/components/ulp/lp_core/include/ulp_lp_core.h index 447c814ddac..d737d638aca 100644 --- a/components/ulp/lp_core/include/ulp_lp_core.h +++ b/components/ulp/lp_core/include/ulp_lp_core.h @@ -31,9 +31,9 @@ typedef struct { uint32_t wakeup_source; /*!< Wakeup source flags */ uint32_t lp_timer_sleep_duration_us; /*!< Sleep duration when ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER is specified. Measurement unit: us */ #if ESP_ROM_HAS_LP_ROM - bool skip_lp_rom_boot; /* !< Skips the LP rom code and boots directly into the app code placed in LP RAM, - this gives faster boot time for time sensitive use-cases at the cost of skipping - setup e.g. of UART */ + bool skip_lp_rom_boot; /*!< Skips the LP rom code and boots directly into the app code placed in LP RAM, + this gives faster boot time for time sensitive use-cases at the cost of skipping + setup e.g. of UART */ #endif //ESP_ROM_HAS_LP_ROM } ulp_lp_core_cfg_t; diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h new file mode 100644 index 00000000000..95b97e13200 --- /dev/null +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_err.h" + +/** + * The LP SPI bus identifier to initiate a transaction on. + */ +typedef uint32_t lp_spi_bus_t; + +/** + * This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes. + */ +typedef struct { + uint32_t tx_length; /*!< Total data length to transmit in bytes */ + uint32_t rx_length; /*!< Total data length to receive in bytes */ + const void *tx_buffer; /*!< Pointer to the transmit buffer. Must be set for master mode transactions. Can be NULL for slave mode transactions. */ + void *rx_buffer; /*!< Pointer to the receive buffer. Must be set for slave mode transactions. Can be NULL for master mode transactions. */ + lp_spi_bus_t bus; /*!< The LP SPI bus to transmit the data on */ + // The following are only used in master mode transactions + int command; /*!< Command data, of which the length is set in the ``command_bits`` field of this structure. */ + uint32_t address; /*!< Address data, of which the length is set in the ``address_bits`` field of this structure. */ + uint8_t command_bits; /*!< Default amount of bits in command phase */ + uint8_t address_bits; /*!< Default amount of bits in address phase */ + uint8_t dummy_bits; /*!< Amount of dummy bits to insert between address and data phase. */ +} lp_spi_transaction_t; + +/** + * @brief Initiate an LP SPI transaction in master mode to transmit device to an SPI device and optionally receive data + * from the device. + * + * @param trans_desc LP SPI transaction configuration descriptor + * @param ticks_to_wait Operation timeout in CPU cycles. Set to -1 to wait forever. + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_ERR_TIMEOUT when the operation times out + */ +esp_err_t lp_core_lp_spi_master_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait); + +/** + * @brief Initiate an LP SPI transaction in slave mode to receive data from an SPI master and optionally transmit data + * back to the master. + * + * @param trans_desc LP SPI transaction configuration descriptor + * @param ticks_to_wait Operation timeout in CPU cycles. Set to -1 to wait forever. + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_ERR_TIMEOUT when the operation times out + */ +esp_err_t lp_core_lp_spi_slave_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/lp_core/lp_core_spi.c b/components/ulp/lp_core/lp_core/lp_core_spi.c new file mode 100644 index 00000000000..9ff1f8a2734 --- /dev/null +++ b/components/ulp/lp_core/lp_core/lp_core_spi.c @@ -0,0 +1,262 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" + +#if SOC_LP_SPI_SUPPORTED + +#include +#include +#include "esp_err.h" +#include "ulp_lp_core_spi.h" +#include "soc/lp_spi_struct.h" + +/* Use the register structure to access LP_SPI module registers */ +lp_spi_dev_t *lp_spi_dev = &LP_SPI; + +static inline esp_err_t lp_core_spi_wait_for_interrupt(int32_t ticks_to_wait) +{ + uint32_t to = 0; + while (!lp_spi_dev->spi_dma_int_raw.reg_trans_done_int_raw) { + if (ticks_to_wait > -1) { + /* If the ticks_to_wait value is not -1, keep track of ticks and + * break from the loop once the timeout is reached. + */ + to++; + if (to >= ticks_to_wait) { + /* Clear interrupt bits */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + return ESP_ERR_TIMEOUT; + } + } + } + + return ESP_OK; +} + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// Public APIs /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// + +esp_err_t lp_core_lp_spi_master_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check + * Note: The Tx buffer is mandatory for this API. + */ + if (trans_desc == NULL || trans_desc->tx_buffer == NULL || trans_desc->tx_length == 0) { + return ESP_ERR_INVALID_ARG; + } + + /* Reset the Tx and Rx FIFOs */ + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 0; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 0; + + /* Clear any previous interrupts. + * Note: LP SPI does not have any DMA access but the interrupt bit lives in the DMA interrupt register. + */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Make sure that we do not have any ongoing transactions */ + if (lp_spi_dev->spi_cmd.reg_usr) { + return ESP_ERR_INVALID_STATE; + } + + /* Configure dummy bits */ + lp_spi_dev->spi_user.reg_usr_dummy = trans_desc->dummy_bits ? 1 : 0; + if (trans_desc->dummy_bits) { + lp_spi_dev->spi_user1.reg_usr_dummy_cyclelen = trans_desc->dummy_bits - 1; + } + + /* Configure the command and command bit length */ + lp_spi_dev->spi_user.reg_usr_command = trans_desc->command_bits ? 1 : 0; + if (trans_desc->command_bits) { + lp_spi_dev->spi_user2.reg_usr_command_bitlen = trans_desc->command_bits - 1; + lp_spi_dev->spi_user2.reg_usr_command_value = lp_spi_dev->spi_ctrl.reg_wr_bit_order ? trans_desc->command : __builtin_bswap32(trans_desc->command << (32 - trans_desc->command_bits)); + } + + /* Configure the address and address bit length */ + lp_spi_dev->spi_user.reg_usr_addr = trans_desc->address_bits ? 1 : 0; + if (trans_desc->address_bits) { + lp_spi_dev->spi_user1.reg_usr_addr_bitlen = trans_desc->address_bits - 1; + lp_spi_dev->spi_addr.reg_usr_addr_value = lp_spi_dev->spi_ctrl.reg_wr_bit_order ? __builtin_bswap32(trans_desc->address) : trans_desc->address << (32 - trans_desc->address_bits); + } + + /* Set data lines */ + lp_spi_dev->spi_user.reg_usr_mosi = 1; + lp_spi_dev->spi_user.reg_usr_miso = trans_desc->rx_buffer ? 1 : 0; + + /* Configure the transaction bit length */ + int tx_bitlen = trans_desc->tx_length * 8; + lp_spi_dev->spi_ms_dlen.reg_ms_data_bitlen = tx_bitlen - 1; + + /* Prepare the data to be transmitted */ + uint32_t tx_idx = 0; + uint32_t rx_idx = 0; + + /* The TRM suggests that the data is sent from and received in the LP_SPI_W0_REG ~ LP_SPI_W15_REG registers. + * The following rules apply: + * 1. The first 64 bytes are sent from/received in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * 2. Bytes 64 - 255 are repeatedly sent from or received in LP_SPI_W15_REG[31:24] + * 3. Subsequent blocks of 256 bytes of data continue to follow the above rules + * + * This driver, however, avoids using the LP_SPI_W15_REG altogether. In other words, + * this driver sends or receives data in chunks of 60 bytes (LP_SPI_W0_REG ~ LP_SPI_W14_REG) + * and does not handle the repeated use of the high-byte of LP_SPI_W15_REG. This design approach + * has been chosen to simplify the data handling logic. + */ + uint8_t max_data_reg_num = (SOC_LP_SPI_MAXIMUM_BUFFER_SIZE / 4) - 1; // 15 + uint8_t max_data_chunk_size = max_data_reg_num * 4; // 60 + while (tx_idx < trans_desc->tx_length) { + /* Store 4 bytes of data in the data buffer registers serially. */ + lp_spi_dev->data_buf[(tx_idx / 4) & max_data_reg_num].reg_buf = *(uint32_t *)(trans_desc->tx_buffer + tx_idx); + tx_idx += 4; + + /* Begin transmission of the data if we have pushed all the data or if we have reached the maximum data chunk size */ + if ((tx_idx >= trans_desc->tx_length) || (tx_idx % max_data_chunk_size) == 0) { + /* Apply the configuration */ + lp_spi_dev->spi_cmd.reg_update = 1; + while (lp_spi_dev->spi_cmd.reg_update) { + ; + } + + /* Start the transaction */ + lp_spi_dev->spi_cmd.reg_usr = 1; + + /* Wait for the transaction to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Fetch the received data if an Rx buffer is provided */ + if (trans_desc->rx_buffer != NULL) { + while (rx_idx < tx_idx) { + *(uint32_t *)(trans_desc->rx_buffer + rx_idx) = lp_spi_dev->data_buf[(rx_idx / 4) & max_data_reg_num].reg_buf; + rx_idx += 4; + // This loop would exit even if we haven't received all the data. + } + } + } + } + + return ret; +} + +esp_err_t lp_core_lp_spi_slave_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check + * Note: The Rx buffer is mandatory for this API. + */ + if (trans_desc == NULL || trans_desc->rx_buffer == NULL || trans_desc->rx_length == 0) { + return ESP_ERR_INVALID_ARG; + } + + /* Reset the Tx and Rx FIFOs */ + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 0; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 0; + + /* Clear any previous interrupts. + * Note: LP SPI does not have any DMA access but the interrupt bit lives in the DMA interrupt register. + */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Set data lines */ + lp_spi_dev->spi_user.reg_usr_mosi = 1; + lp_spi_dev->spi_user.reg_usr_miso = 1; + + /* Configure the transaction bit length */ + int rx_bitlen = trans_desc->rx_length * 8; + lp_spi_dev->spi_ms_dlen.reg_ms_data_bitlen = rx_bitlen - 1; + + /* Prepare the data to be received */ + uint32_t rx_idx = 0; + uint32_t rcvd_bitlen = 0; + uint32_t rcvd_length_in_bytes = 0; + + /* The LP SPI slave receives data in the LP_SPI_W0_REG ~ LP_SPI_W15_REG registers. + * The following rules apply: + * 1. The first 64 bytes are received in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * 2. The next 64 bytes are overwritten in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * + * Since the peripheral has no protection against overwriting the data, we restrict the + * driver to receive up to 64 bytes of data at a time. + */ + uint32_t length_in_bytes = trans_desc->rx_length; + if (trans_desc->rx_length > SOC_LP_SPI_MAXIMUM_BUFFER_SIZE) { + /* Truncate the length to the maximum buffer size */ + length_in_bytes = SOC_LP_SPI_MAXIMUM_BUFFER_SIZE; + } + + while (rx_idx < length_in_bytes) { + /* Wait for the transmission to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Fetch the received bit length */ + rcvd_bitlen = lp_spi_dev->spi_slave1.reg_slv_data_bitlen > (trans_desc->rx_length * 8) ? (trans_desc->rx_length * 8) : lp_spi_dev->spi_slave1.reg_slv_data_bitlen; + rcvd_length_in_bytes = (rcvd_bitlen + 7) / 8; + + /* Read the received data */ + while (rx_idx < rcvd_length_in_bytes) { + *(uint32_t *)(trans_desc->rx_buffer + rx_idx) = lp_spi_dev->data_buf[(rx_idx / 4)].reg_buf; + rx_idx += 4; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + } + + /* Prepare data for transmission if a Tx buffer is provided */ + if (trans_desc->tx_buffer != NULL) { + uint32_t tx_idx = 0; + uint32_t length_in_bytes = trans_desc->tx_length; + if (length_in_bytes > SOC_LP_SPI_MAXIMUM_BUFFER_SIZE) { + /* Truncate the length to the maximum buffer size */ + length_in_bytes = SOC_LP_SPI_MAXIMUM_BUFFER_SIZE; + } + + while (tx_idx < length_in_bytes) { + /* Store 4 bytes of data in the data buffer registers serially. */ + lp_spi_dev->data_buf[(tx_idx / 4)].reg_buf = *(uint32_t *)(trans_desc->tx_buffer + tx_idx); + tx_idx += 4; + } + + /* Apply the configuration */ + lp_spi_dev->spi_cmd.reg_update = 1; + while (lp_spi_dev->spi_cmd.reg_update) { + ; + } + + /* Start the transaction */ + lp_spi_dev->spi_cmd.reg_usr = 1; + + /* Wait for the transaction to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + } + + return ret; +} + +#endif /* SOC_LP_SPI_SUPPORTED */ diff --git a/components/ulp/lp_core/lp_core_spi.c b/components/ulp/lp_core/lp_core_spi.c new file mode 100644 index 00000000000..0def39cc015 --- /dev/null +++ b/components/ulp/lp_core/lp_core_spi.c @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "lp_core_spi.h" +#include "driver/rtc_io.h" +#include "driver/lp_io.h" +#include "hal/rtc_io_types.h" +#include "include/lp_core_spi.h" +#include "soc/lp_spi_struct.h" +#include "soc/lp_gpio_sig_map.h" +#include "soc/lpperi_struct.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk_tree_common.h" +#include "hal/spi_ll.h" + +static const char *LP_SPI_TAG = "lp_spi"; + +/* Use the LP SPI register structure to access peripheral registers */ +lp_spi_dev_t *lp_spi_dev = &LP_SPI; + +static esp_err_t lp_spi_config_io(gpio_num_t pin, rtc_gpio_mode_t direction, uint32_t out_pad_idx, uint32_t in_pad_idx) +{ + esp_err_t ret = ESP_OK; + + /* If pin is -1, then it is not connected to any LP_IO */ + if (pin == -1) { + return ESP_OK; + } + + /* Initialize LP_IO */ + ESP_RETURN_ON_ERROR(rtc_gpio_init(pin), LP_SPI_TAG, "LP IO Init failed for GPIO %d", pin); + + /* Set LP_IO direction */ + ESP_RETURN_ON_ERROR(rtc_gpio_set_direction(pin, direction), LP_SPI_TAG, "LP IO Set direction failed for %d", pin); + + /* Connect the LP SPI signals to the LP_IO Matrix */ + ESP_RETURN_ON_ERROR(lp_gpio_connect_out_signal(pin, out_pad_idx, 0, 0), LP_SPI_TAG, "LP IO Matrix connect out signal failed for %d", pin); + ESP_RETURN_ON_ERROR(lp_gpio_connect_in_signal(pin, in_pad_idx, 0), LP_SPI_TAG, "LP IO Matrix connect in signal failed for %d", pin); + + return ret; +} + +static esp_err_t lp_spi_bus_init_io(const lp_spi_bus_config_t *bus_config) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check */ +#if SOC_LP_GPIO_MATRIX_SUPPORTED + /* LP SPI signals can be routed to any LP_IO */ + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(bus_config->mosi_io_num)), ESP_FAIL, LP_SPI_TAG, "mosi_io_num error"); + ESP_RETURN_ON_FALSE((bus_config->miso_io_num == -1) || (rtc_gpio_is_valid_gpio(bus_config->miso_io_num)), ESP_FAIL, LP_SPI_TAG, "miso_io_num error"); + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(bus_config->sclk_io_num)), ESP_FAIL, LP_SPI_TAG, "sclk_io_num error"); + + /* Configure miso pin*/ + ret = lp_spi_config_io(bus_config->miso_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_Q_PAD_OUT_IDX, LP_SPI_Q_PAD_IN_IDX); + /* Configure mosi pin */ + ret = lp_spi_config_io(bus_config->mosi_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_D_PAD_OUT_IDX, LP_SPI_D_PAD_IN_IDX); + /* Configure sclk pin */ + ret = lp_spi_config_io(bus_config->sclk_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_CK_PAD_OUT_IDX, LP_SPI_CK_PAD_IN_IDX); +#else +#error "LP SPI bus initialization is not supported without LP GPIO Matrix." +#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */ + + return ret; +} + +static esp_err_t lp_spi_cs_pin_init(int cs_io_num) +{ + esp_err_t ret = ESP_OK; + +#if SOC_LP_GPIO_MATRIX_SUPPORTED + /* CS signal can be routed to any LP_IO */ + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(cs_io_num)), ESP_FAIL, LP_SPI_TAG, "cs_io_num error"); + + /* Configure CS pin */ + ret = lp_spi_config_io(cs_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_CS_PAD_OUT_IDX, LP_SPI_CS_PAD_IN_IDX); +#else +#error "LP SPI device Chip Select (CS) initialization is not supported without LP GPIO Matrix." +#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */ + + return ret; +} + +static void lp_spi_enable_clock_gate(void) +{ + lpperi_dev_t *lp_peri_dev = &LPPERI; + PERIPH_RCC_ATOMIC() { + (void)__DECLARE_RCC_ATOMIC_ENV; // Avoid warnings for unused variable __DECLARE_RCC_ATOMIC_ENV + lp_peri_dev->clk_en.ck_en_lp_spi = 1; + } +} + +static esp_err_t lp_spi_clock_init(const lp_spi_device_config_t *dev_config) +{ + esp_err_t ret = ESP_OK; + + /* Max requested clock frequency cannot be more than the LP_FAST_CLK frequency */ + uint32_t max_clock_source_hz = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + ESP_RETURN_ON_FALSE(dev_config->clock_speed_hz <= max_clock_source_hz, ESP_ERR_INVALID_ARG, LP_SPI_TAG, "Invalid clock speed for SPI device. Max allowed = %ld Hz", max_clock_source_hz); + + /* Set the duty cycle. If not specified, use 50% */ + int duty_cycle = dev_config->duty_cycle ? dev_config->duty_cycle : 128; + + /* Calculate the clock pre-div values. We use the HP SPI LL function here for the calculation. */ + spi_ll_clock_val_t spi_clock; + spi_ll_master_cal_clock(max_clock_source_hz, dev_config->clock_speed_hz, duty_cycle, &spi_clock); + lp_spi_dev->spi_clock.val = spi_clock; + + return ret; +} + +static void lp_spi_master_init(void) +{ + /* Initialize the LP SPI in master mode. + * (We do not have a HAL/LL layer for LP SPI, yet, so let's use the LP SPI registers directly). + */ + + /* Clear Slave mode to enable Master mode */ + lp_spi_dev->spi_slave.reg_slave_mode = 0; + lp_spi_dev->spi_slave.reg_clk_mode = 0; + + /* Reset CS timing */ + lp_spi_dev->spi_user1.reg_cs_setup_time = 0; + lp_spi_dev->spi_user1.reg_cs_hold_time = 0; + + /* Use all 64 bytes of the Tx/Rx buffers in CPU controlled transfer */ + lp_spi_dev->spi_user.reg_usr_mosi_highpart = 0; + lp_spi_dev->spi_user.reg_usr_miso_highpart = 0; +} + +static void lp_spi_slave_init(void) +{ + /* Set Slave mode */ + lp_spi_dev->spi_slave.reg_slave_mode = 1; + + /* Reset the SPI peripheral */ + lp_spi_dev->spi_slave.reg_soft_reset = 1; + lp_spi_dev->spi_slave.reg_soft_reset = 0; + + /* Configure slave */ + lp_spi_dev->spi_clock.val = 0; + lp_spi_dev->spi_user.val = 0; + lp_spi_dev->spi_ctrl.val = 0; + lp_spi_dev->spi_user.reg_doutdin = 1; //we only support full duplex + lp_spi_dev->spi_user.reg_sio = 0; + + /* Use all 64 bytes of the Tx/Rx buffers in CPU controlled transfer */ + lp_spi_dev->spi_user.reg_usr_miso_highpart = 0; + lp_spi_dev->spi_user.reg_usr_mosi_highpart = 0; +} + +static void lp_spi_master_setup_device(const lp_spi_device_config_t *dev_config) +{ + /* Configure transmission bit order */ + lp_spi_dev->spi_ctrl.reg_rd_bit_order = dev_config->flags & LP_SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0; + lp_spi_dev->spi_ctrl.reg_wr_bit_order = dev_config->flags & LP_SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0; + + /* Configure SPI mode in master mode */ + if (dev_config->spi_mode == 0) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_ck_out_edge = 0; + } else if (dev_config->spi_mode == 1) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_ck_out_edge = 1; + } else if (dev_config->spi_mode == 2) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_ck_out_edge = 1; + } else if (dev_config->spi_mode == 3) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_ck_out_edge = 0; + } + + /* Configure the polarity of the CS line */ + lp_spi_dev->spi_misc.reg_master_cs_pol = dev_config->flags & LP_SPI_DEVICE_CS_ACTIVE_HIGH ? 1 : 0; + + /* Configure half-duplex (0) or full-duplex (1) mode for LP SPI master */ + lp_spi_dev->spi_user.reg_doutdin = dev_config->flags & LP_SPI_DEVICE_HALF_DUPLEX ? 0 : 1; + + /* Configure 3-Wire half-duplex mode */ + lp_spi_dev->spi_user.reg_sio = dev_config->flags & LP_SPI_DEVICE_3WIRE ? 1 : 0; + + /* Configure CS setup and hold times */ + lp_spi_dev->spi_user1.reg_cs_setup_time = dev_config->cs_ena_pretrans == 0 ? 0 : dev_config->cs_ena_pretrans - 1; + lp_spi_dev->spi_user.reg_cs_setup = dev_config->cs_ena_pretrans ? 1 : 0; + lp_spi_dev->spi_user1.reg_cs_hold_time = dev_config->cs_ena_posttrans; + lp_spi_dev->spi_user.reg_cs_hold = dev_config->cs_ena_posttrans ? 1 : 0; + + /* Select the CS pin */ + lp_spi_dev->spi_misc.reg_cs0_dis = 0; +} + +static void lp_spi_slave_setup_device(const lp_spi_slave_config_t *slave_config) +{ + /* Configure transmission bit order */ + lp_spi_dev->spi_ctrl.reg_rd_bit_order = slave_config->flags & LP_SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0; + lp_spi_dev->spi_ctrl.reg_wr_bit_order = slave_config->flags & LP_SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0; + + /* Configure SPI mode in slave mode */ + if (slave_config->spi_mode == 0) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_rsck_i_edge = 0; + lp_spi_dev->spi_user.reg_tsck_i_edge = 0; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 0; + } else if (slave_config->spi_mode == 1) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_rsck_i_edge = 1; + lp_spi_dev->spi_user.reg_tsck_i_edge = 1; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 1; + } else if (slave_config->spi_mode == 2) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_rsck_i_edge = 1; + lp_spi_dev->spi_user.reg_tsck_i_edge = 1; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 0; + } else if (slave_config->spi_mode == 3) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_rsck_i_edge = 0; + lp_spi_dev->spi_user.reg_tsck_i_edge = 0; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 1; + } + + if (slave_config->flags & LP_SPI_DEVICE_CS_ACTIVE_HIGH) { + ESP_LOGW(LP_SPI_TAG, "Active high CS line is not supported in slave mode. Using active low CS line."); + } + lp_spi_dev->spi_misc.reg_slave_cs_pol = 0; + + if (slave_config->flags & LP_SPI_DEVICE_HALF_DUPLEX) { + ESP_LOGW(LP_SPI_TAG, "Half-duplex mode is not supported in slave mode. Using full-duplex mode."); + } + lp_spi_dev->spi_user.reg_doutdin = 1; + + /* Configure 3-Wire half-duplex mode */ + lp_spi_dev->spi_user.reg_sio = slave_config->flags & LP_SPI_DEVICE_3WIRE ? 1 : 0; + + /* Select the CS pin */ + lp_spi_dev->spi_misc.reg_cs0_dis = 0; +} + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// Public APIs /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// + +esp_err_t lp_core_lp_spi_bus_initialize(lp_spi_host_t host_id, const lp_spi_bus_config_t *bus_config) +{ + (void)host_id; + + /* Sanity check arguments */ + if (bus_config == NULL) { + return ESP_ERR_INVALID_ARG; + } + + /* Connect the LP SPI peripheral to a "bus", i.e. a set of + * GPIO pins defined in the bus_config structure. + */ + esp_err_t ret = lp_spi_bus_init_io(bus_config); + + return ret; +} + +esp_err_t lp_core_lp_spi_bus_add_device(lp_spi_host_t host_id, const lp_spi_device_config_t *dev_config) +{ + (void)host_id; + + esp_err_t ret = ESP_OK; + + /* Configure the CS pin */ + ESP_RETURN_ON_ERROR(lp_spi_cs_pin_init(dev_config->cs_io_num), LP_SPI_TAG, "CS pin initialization failed"); + + /* Enable the LP SPI clock gate */ + lp_spi_enable_clock_gate(); + + /* Lazy initialize the LP SPI in master mode */ + lp_spi_master_init(); + + /* Configure clock */ + ESP_RETURN_ON_ERROR(lp_spi_clock_init(dev_config), LP_SPI_TAG, "Clock initialization failed"); + + /* Setup the SPI device */ + lp_spi_master_setup_device(dev_config); + + return ret; +} + +esp_err_t lp_core_lp_spi_slave_initialize(lp_spi_host_t host_id, const lp_spi_slave_config_t *slave_config) +{ + (void)host_id; + + esp_err_t ret = ESP_OK; + + /* Configure the CS pin */ + ESP_RETURN_ON_ERROR(lp_spi_cs_pin_init(slave_config->cs_io_num), LP_SPI_TAG, "CS pin initialization failed"); + + /* Enable the LP SPI clock gate */ + lp_spi_enable_clock_gate(); + + /* Initialize the LP SPI in slave mode */ + lp_spi_slave_init(); + + /* Setup the SPI device */ + lp_spi_slave_setup_device(slave_config); + + return ret; +} diff --git a/components/ulp/test_apps/.build-test-rules.yml b/components/ulp/test_apps/.build-test-rules.yml index b601d66f143..50e056d9031 100644 --- a/components/ulp/test_apps/.build-test-rules.yml +++ b/components/ulp/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/ulp/test_apps/lp_core: disable: - if: SOC_LP_CORE_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: test not pass, should be re-enable # TODO: [ESP32C5] IDF-10336 depends_components: - ulp diff --git a/components/ulp/test_apps/lp_core/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/main/CMakeLists.txt index 20b618d0596..59bd723f445 100644 --- a/components/ulp/test_apps/lp_core/main/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/main/CMakeLists.txt @@ -8,6 +8,10 @@ if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) list(APPEND app_sources "test_lp_core_uart.c") endif() +if(CONFIG_SOC_LP_SPI_SUPPORTED) + list(APPEND app_sources "test_lp_core_spi.c") +endif() + set(lp_core_sources "lp_core/test_main.c") set(lp_core_sources_counter "lp_core/test_main_counter.c") @@ -25,6 +29,11 @@ if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) set(lp_core_sources_uart "lp_core/test_main_uart.c") endif() +if(CONFIG_SOC_LP_SPI_SUPPORTED) + set(lp_core_sources_spi_master "lp_core/test_main_spi_master.c") + set(lp_core_sources_spi_slave "lp_core/test_main_spi_slave.c") +endif() + idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "lp_core" REQUIRES ulp unity esp_timer test_utils @@ -49,3 +58,8 @@ endif() if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) ulp_embed_binary(lp_core_test_app_uart "${lp_core_sources_uart}" "${lp_core_exp_dep_srcs}") endif() + +if(CONFIG_SOC_LP_SPI_SUPPORTED) + ulp_embed_binary(lp_core_test_app_spi_master "${lp_core_sources_spi_master}" "${lp_core_exp_dep_srcs}") + ulp_embed_binary(lp_core_test_app_spi_slave "${lp_core_sources_spi_slave}" "${lp_core_exp_dep_srcs}") +endif() diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_master.c b/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_master.c new file mode 100644 index 00000000000..f7872dbcfc5 --- /dev/null +++ b/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_master.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "ulp_lp_core_spi.h" +#include "test_shared.h" + +volatile lp_core_test_commands_t spi_test_cmd = LP_CORE_NO_COMMAND; + +volatile uint8_t spi_master_tx_buf[100] = {0}; +volatile uint8_t spi_master_rx_buf[100] = {0}; +volatile uint32_t spi_tx_len = 0; + +int main(void) +{ + /* Wait for the HP core to start the test */ + while (spi_test_cmd == LP_CORE_NO_COMMAND) { + + } + + /* Setup SPI transaction */ + lp_spi_transaction_t trans_desc = { + .tx_length = spi_tx_len, + .rx_length = spi_tx_len, + .tx_buffer = (uint8_t *)spi_master_tx_buf, + .rx_buffer = (uint8_t *)spi_master_rx_buf, + }; + + /* Transmit data */ + lp_core_lp_spi_master_transfer(&trans_desc, -1); + + /* Synchronize with the HP core running the test */ + spi_test_cmd = LP_CORE_NO_COMMAND; + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_slave.c b/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_slave.c new file mode 100644 index 00000000000..81b208295e5 --- /dev/null +++ b/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_slave.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "ulp_lp_core_spi.h" +#include "test_shared.h" + +volatile lp_core_test_command_reply_t spi_test_cmd_reply = LP_CORE_COMMAND_NOK; + +volatile uint8_t spi_slave_tx_buf[100] = {0}; +volatile uint8_t spi_slave_rx_buf[100] = {0}; +volatile uint32_t spi_rx_len = 0; + +int main(void) +{ + /* Setup SPI transaction */ + lp_spi_transaction_t trans_desc = { + .rx_length = spi_rx_len, + .rx_buffer = (uint8_t *)spi_slave_rx_buf, + .tx_buffer = NULL, + }; + + /* Receive data */ + lp_core_lp_spi_slave_transfer(&trans_desc, -1); + + /* Synchronize with the HP core running the test */ + spi_test_cmd_reply = LP_CORE_COMMAND_OK; + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h b/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h index 8f27a65915d..8fc1c431400 100644 --- a/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h +++ b/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h @@ -24,6 +24,7 @@ typedef enum { LP_CORE_LP_UART_READ_TEST, LP_CORE_LP_UART_MULTI_BYTE_READ_TEST, LP_CORE_LP_UART_PRINT_TEST, + LP_CORE_LP_SPI_WRITE_READ_TEST, LP_CORE_NO_COMMAND, } lp_core_test_commands_t; diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_spi.c b/components/ulp/test_apps/lp_core/main/test_lp_core_spi.c new file mode 100644 index 00000000000..b23e99bd099 --- /dev/null +++ b/components/ulp/test_apps/lp_core/main/test_lp_core_spi.c @@ -0,0 +1,254 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "lp_core_test_app_spi_master.h" +#include "lp_core_test_app_spi_slave.h" +#include "ulp_lp_core.h" +#include "lp_core_spi.h" +#include "unity.h" +#include "test_utils.h" +#include "esp_log.h" +#include "test_shared.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +extern const uint8_t lp_core_main_spi_master_bin_start[] asm("_binary_lp_core_test_app_spi_master_bin_start"); +extern const uint8_t lp_core_main_spi_master_bin_end[] asm("_binary_lp_core_test_app_spi_master_bin_end"); +extern const uint8_t lp_core_main_spi_slave_bin_start[] asm("_binary_lp_core_test_app_spi_slave_bin_start"); +extern const uint8_t lp_core_main_spi_slave_bin_end[] asm("_binary_lp_core_test_app_spi_slave_bin_end"); + +static const char* TAG = "lp_core_spi_test"; + +#define TEST_GPIO_PIN_MISO 6 +#define TEST_GPIO_PIN_MOSI 7 +#define TEST_GPIO_PIN_CLK 8 +#define TEST_GPIO_PIN_CS 4 + +#define TEST_DATA_LEN_BYTES 42 +uint8_t expected_data[100] = {0}; + +static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) +{ + TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, (firmware_end - firmware_start)) == ESP_OK); + TEST_ASSERT(ulp_lp_core_run(cfg) == ESP_OK); +} + +static void setup_test_data(void) +{ + uint8_t *tx_data = (uint8_t *)&ulp_spi_master_tx_buf; + ulp_spi_tx_len = TEST_DATA_LEN_BYTES; + + /* Setup test data */ + for (int i = 0; i < ulp_spi_tx_len; i++) { + tx_data[i] = (i + 1) % 256; + expected_data[i] = tx_data[i]; + } +} + +static void setup_expected_data(void) +{ + ulp_spi_rx_len = TEST_DATA_LEN_BYTES; + + /* Setup expected data */ + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + expected_data[i] = (i + 1) % 256; + } +} + +/* Base LP SPI bus settings */ +lp_spi_host_t host_id = 0; +lp_spi_bus_config_t bus_config = { + .miso_io_num = TEST_GPIO_PIN_MISO, + .mosi_io_num = TEST_GPIO_PIN_MOSI, + .sclk_io_num = TEST_GPIO_PIN_CLK, +}; + +/* Base LP SPI device settings */ +lp_spi_device_config_t device = { + .cs_io_num = TEST_GPIO_PIN_CS, + .spi_mode = 0, + .clock_speed_hz = 10 * 1000, // 10 MHz + .duty_cycle = 128, // 50% duty cycle +}; + +/* Base LP SPI slave device settings */ +lp_spi_slave_config_t slv_device = { + .cs_io_num = TEST_GPIO_PIN_CS, + .spi_mode = 0, +}; + +static void lp_spi_master_init(int spi_flags, bool setup_master_loop_back) +{ + /* Initialize LP SPI bus */ + /* Setup loop back for tests which do not use an LP SPI slave for looping back the data. */ + bus_config.miso_io_num = setup_master_loop_back ? TEST_GPIO_PIN_MOSI : TEST_GPIO_PIN_MISO; + TEST_ASSERT(lp_core_lp_spi_bus_initialize(host_id, &bus_config) == ESP_OK); + + /* Add LP SPI device */ + device.flags = spi_flags; + TEST_ASSERT(lp_core_lp_spi_bus_add_device(host_id, &device) == ESP_OK); +} + +static void lp_spi_slave_init(int spi_flags) +{ + /* Initialize LP SPI bus */ + TEST_ASSERT(lp_core_lp_spi_bus_initialize(host_id, &bus_config) == ESP_OK); + + /* Add LP SPI slave device */ + if (spi_flags != 0) { + slv_device.flags = spi_flags; + } + TEST_ASSERT(lp_core_lp_spi_slave_initialize(host_id, &slv_device) == ESP_OK); +} + +static void lp_spi_master_execute_test(bool wait_for_slave_ready) +{ + /* Load and run the LP core firmware */ + ulp_lp_core_cfg_t lp_cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_spi_master_bin_start, lp_core_main_spi_master_bin_end); + + if (wait_for_slave_ready) { + /* Wait for the HP SPI device to be initialized */ + unity_wait_for_signal("LP SPI slave ready"); + } + + /* Setup test data */ + setup_test_data(); + + /* Start the test */ + ulp_spi_test_cmd = LP_CORE_LP_SPI_WRITE_READ_TEST; + + while (ulp_spi_test_cmd != LP_CORE_NO_COMMAND) { + /* Wait for the test to complete */ + vTaskDelay(1); + } + + /* Verify the received data if we expect the data to be looped back from the LP SPI slave */ + uint8_t *rx_data = (uint8_t *)&ulp_spi_master_rx_buf; + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + ESP_LOGI(TAG, "LP SPI master received data: 0x%02x", rx_data[i]); + } + + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_data, ulp_spi_tx_len); +} + +static void lp_spi_slave_execute_test(void) +{ + /* Load and run the LP core firmware */ + ulp_lp_core_cfg_t lp_cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_spi_slave_bin_start, lp_core_main_spi_slave_bin_end); + + /* Setup expected test data */ + setup_expected_data(); + + /* Send signal to LP SPI master */ + unity_send_signal("LP SPI slave ready"); + + /* Wait for the test to complete */ + while (ulp_spi_test_cmd_reply != LP_CORE_COMMAND_OK) { + vTaskDelay(1); + } + + /* Verify the received data */ + uint8_t *rx_data = (uint8_t *)&ulp_spi_slave_rx_buf; + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + ESP_LOGI(TAG, "LP SPI slave received data: 0x%02x", rx_data[i]); + } + + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_data, TEST_DATA_LEN_BYTES); +} + +void test_lp_spi_master(void) +{ + /* Initialize LP SPI in master mode */ + lp_spi_master_init(0, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave(void) +{ + /* Initialize LP SPI in slave mode */ + lp_spi_slave_init(0); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} +void test_lp_spi_master_3wire(void) +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_3WIRE; + lp_spi_master_init(spi_flags, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave_3wire(void) +{ + /* Initialize LP SPI in slave mode */ + int spi_flags = LP_SPI_DEVICE_3WIRE; + lp_spi_slave_init(spi_flags); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} + +void test_lp_spi_master_lsbfirst(void) +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_BIT_LSBFIRST; + lp_spi_master_init(spi_flags, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave_lsbfirst(void) +{ + /* Initialize LP SPI in slave mode */ + int spi_flags = LP_SPI_DEVICE_BIT_LSBFIRST; + lp_spi_slave_init(spi_flags); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} + +/* Test LP-SPI master loopback */ +TEST_CASE("LP-Core LP-SPI master loopback test", "[lp_core]") +{ + /* Initialize LP SPI in master mode */ + lp_spi_master_init(0, true); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(false); +} + +/* Test LP-SPI master loopback with active low CS line */ +TEST_CASE("LP-Core LP-SPI master loopback test with active high CS line", "[lp_core]") +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_CS_ACTIVE_HIGH; + lp_spi_master_init(spi_flags, true); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(false); +} + +/* Test LP-SPI master and LP-SPI slave communication */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI slave read write test", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master, test_lp_spi_slave); + +/* Test LP-SPI master in 3-Wire SPI mode */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI slave in 3-Wire SPI mode", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master_3wire, test_lp_spi_slave_3wire); + +/* Test LP-SPI master and LP-SPI slave in LSB first mode */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI in LSB first SPI mode", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master_lsbfirst, test_lp_spi_slave_lsbfirst); diff --git a/components/ulp/test_apps/lp_core/pytest_lp_core.py b/components/ulp/test_apps/lp_core/pytest_lp_core.py index 24fdcd3bdfe..370632de830 100644 --- a/components/ulp/test_apps/lp_core/pytest_lp_core.py +++ b/components/ulp/test_apps/lp_core/pytest_lp_core.py @@ -4,6 +4,7 @@ from pytest_embedded import Dut +# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10336 @pytest.mark.esp32c6 @pytest.mark.esp32p4 @pytest.mark.generic diff --git a/components/usb/CMakeLists.txt b/components/usb/CMakeLists.txt index 8eca16596fe..8f2ab8dc12b 100644 --- a/components/usb/CMakeLists.txt +++ b/components/usb/CMakeLists.txt @@ -29,6 +29,10 @@ if(CONFIG_SOC_USB_OTG_SUPPORTED) list(APPEND priv_includes "private_include") endif() +if(CONFIG_USB_HOST_HUBS_SUPPORTED) + list(APPEND srcs "ext_hub.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${include} PRIV_INCLUDE_DIRS ${priv_includes} diff --git a/components/usb/Kconfig b/components/usb/Kconfig index ac71a7125e6..1c333f870b8 100644 --- a/components/usb/Kconfig +++ b/components/usb/Kconfig @@ -46,73 +46,85 @@ menu "USB-OTG" bool "Periodic OUT" endchoice - menu "Root Hub configuration" - - config USB_HOST_DEBOUNCE_DELAY_MS - int "Debounce delay in ms" - default 250 + menu "Hub Driver Configuration" + + menu "Root Port configuration" + + config USB_HOST_DEBOUNCE_DELAY_MS + int "Debounce delay in ms" + default 250 + help + On connection of a USB device, the USB 2.0 specification requires + a "debounce interval with a minimum duration of 100ms" to allow the connection to stabilize + (see USB 2.0 chapter 7.1.7.3 for more details). + During the debounce interval, no new connection/disconnection events are registered. + + The default value is set to 250 ms to be safe. + + config USB_HOST_RESET_HOLD_MS + int "Reset hold in ms" + default 30 + help + The reset signaling can be generated on any Hub or Host Controller port by request from + the USB System Software. The USB 2.0 specification requires that "the reset signaling must + be driven for a minimum of 10ms" (see USB 2.0 chapter 7.1.7.5 for more details). + After the reset, the hub port will transition to the Enabled state (refer to Section 11.5). + + The default value is set to 30 ms to be safe. + + config USB_HOST_RESET_RECOVERY_MS + int "Reset recovery delay in ms" + default 30 + help + After a port stops driving the reset signal, the USB 2.0 specification requires that + the "USB System Software guarantees a minimum of 10 ms for reset recovery" before the + attached device is expected to respond to data transfers (see USB 2.0 chapter 7.1.7.3 for + more details). + The device may ignore any data transfers during the recovery interval. + + The default value is set to 30 ms to be safe. + + + config USB_HOST_SET_ADDR_RECOVERY_MS + int "SetAddress() recovery time in ms" + default 10 + help + "After successful completion of the Status stage, the device is allowed a SetAddress() + recovery interval of 2 ms. At the end of this interval, the device must be able to accept + Setup packets addressed to the new address. Also, at the end of the recovery interval, the + device must not respond to tokens sent to the old address (unless, of course, the old and new + address is the same)." See USB 2.0 chapter 9.2.6.3 for more details. + + The default value is set to 10 ms to be safe. + + endmenu #Root Hub configuration + + config USB_HOST_HUBS_SUPPORTED + bool "Support Hubs" + default n help - On connection of a USB device, the USB 2.0 specification requires a "debounce interval with a minimum - duration of 100ms" to allow the connection to stabilize (see USB 2.0 chapter 7.1.7.3 for more details). - During the debounce interval, no new connection/disconnection events are registered. - - The default value is set to 250 ms to be safe. + Enables support of external Hubs. - config USB_HOST_RESET_HOLD_MS - int "Reset hold in ms" - default 30 + config USB_HOST_HUB_MULTI_LEVEL + depends on USB_HOST_HUBS_SUPPORTED + bool "Support multiple Hubs" + default y help - The reset signaling can be generated on any Hub or Host Controller port by request from the USB System - Software. The USB 2.0 specification requires that "the reset signaling must be driven for a minimum of - 10ms" (see USB 2.0 chapter 7.1.7.5 for more details). After the reset, the hub port will transition to - the Enabled state (refer to Section 11.5). + Enables support for connecting multiple Hubs simultaneously. - The default value is set to 30 ms to be safe. - - config USB_HOST_RESET_RECOVERY_MS - int "Reset recovery delay in ms" - default 30 - help - After a port stops driving the reset signal, the USB 2.0 specification requires that the "USB System - Software guarantees a minimum of 10 ms for reset recovery" before the attached device is expected to - respond to data transfers (see USB 2.0 chapter 7.1.7.3 for more details). The device may ignore any - data transfers during the recovery interval. - - The default value is set to 30 ms to be safe. - - - config USB_HOST_SET_ADDR_RECOVERY_MS - int "SetAddress() recovery time in ms" - default 10 - help - "After successful completion of the Status stage, the device is allowed a SetAddress() recovery - interval of 2 ms. At the end of this interval, the device must be able to accept Setup packets - addressed to the new address. Also, at the end of the recovery interval, the device must not respond to - tokens sent to the old address (unless, of course, the old and new address is the same)." See USB 2.0 - chapter 9.2.6.3 for more details. - - The default value is set to 10 ms to be safe. - - endmenu #Root Hub configuration + endmenu #Hub Driver Configuration config USB_HOST_ENABLE_ENUM_FILTER_CALLBACK bool "Enable enumeration filter callback" default n help - The enumeration filter callback is called before enumeration of each newly attached device. This callback - allows users to control whether a device should be enumerated, and what configuration number to use when - enumerating a device. + The enumeration filter callback is called before enumeration of each newly attached device. + This callback allows users to control whether a device should be enumerated, and what configuration + number to use when enumerating a device. If enabled, the enumeration filter callback can be set via 'usb_host_config_t' when calling 'usb_host_install()'. - config USB_HOST_EXT_HUB_SUPPORT - depends on IDF_EXPERIMENTAL_FEATURES - bool "Support USB HUB (Experimental)" - default n - help - Feature is under development. - # Hidden or compatibility options config USB_OTG_SUPPORTED # Invisible config kept for compatibility diff --git a/components/usb/ext_hub.c b/components/usb/ext_hub.c new file mode 100644 index 00000000000..fe5692ba79a --- /dev/null +++ b/components/usb/ext_hub.c @@ -0,0 +1,1598 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_err.h" +#include "esp_log.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "hal/usb_dwc_hal.h" // for OTG_HSPHY_INTERFACE +#include "usb_private.h" +#include "ext_hub.h" +#include "usb/usb_helpers.h" + +typedef struct ext_port_s *ext_port_hdl_t; /* This will be implemented during ext_port driver implementation */ + +#define EXT_HUB_STATUS_CHANGE_FLAG (1 << 0) +#define EXT_HUB_STATUS_PORT1_CHANGE_FLAG (1 << 1) +#define EXT_HUB_CTRL_TRANSFER_MAX_DATA_LEN CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE + +/** + * @brief Device state + * + * Global state of the Device + */ +typedef enum { + EXT_HUB_STATE_ATTACHED, /**< Device attached, but not state is unknown (no: Hub Descriptor, Device status and Hub status) */ + EXT_HUB_STATE_CONFIGURED, /**< Device attached and configured (has Hub Descriptor, Device status and Hub status were requested )*/ + EXT_HUB_STATE_SUSPENDED, /**< Device suspended */ + EXT_HUB_STATE_RELEASED, /**< Device released by USB Host driver (device could still be present on bus) */ + EXT_HUB_STATE_FAILED /**< Device has internal error */ +} ext_hub_state_t; + +/** + * @brief Device stages + * + * During the lifecycle, Hub requires different actions. To implement interaction with external Hub the FSM, based on these stages is using. + * + * Entry: + * - Every new attached external Hub should start from EXT_HUB_STAGE_GET_HUB_DESCRIPTOR. Without Fetching Hub Descriptor, device is not configured and doesn't have any ports. + * - After handling the response during EXT_HUB_STAGE_CHECK_HUB_DESCRIPTOR, the External Hub Driver configures the Device according to the data from Hub Descriptor. + * - After completion of any stage, the Device does back to the IDLE stage and waits for another request. Source of the request could be: EP1 INT callback (the Hub or Ports changes) or external call. + * - Stages, that don't required response handling could not end up with fail. + */ +typedef enum { + // Device in IDLE state + EXT_HUB_STAGE_IDLE = 0, /**< Device in idle state and do not fulfill any actions */ + // Stages, required response handling + EXT_HUB_STAGE_GET_DEVICE_STATUS, /**< Device requests Device Status. For more details, refer to 9.4.5 Get Status of usb_20 */ + EXT_HUB_STAGE_CHECK_DEVICE_STATUS, /**< Device received the Device Status and required its' handling */ + EXT_HUB_STAGE_GET_HUB_DESCRIPTOR, /**< Device requests Hub Descriptor. For more details, refer to 11.24.2.5 Get Hub Descriptor of usb_20 */ + EXT_HUB_STAGE_CHECK_HUB_DESCRIPTOR, /**< Device received the Hub Descriptor and requires its' handling */ + EXT_HUB_STAGE_GET_HUB_STATUS, /**< Device requests Hub Status. For more details, refer to 11.24.2.6 Get Hub Status of usb_20 */ + EXT_HUB_STAGE_CHECK_HUB_STATUS, /**< Device received the Hub Status and requires its' handling */ + // Stages, don't required response handling + EXT_HUB_STAGE_PORT_FEATURE, /**< Device completed the Port Feature class-specific request (Set Feature or Clear Feature). For more details, refer to 11.24.2 Class-specific Requests of usb_20 */ + EXT_HUB_STAGE_PORT_STATUS_REQUEST, /**< Device completed the Port Get Status class-specific request. For more details, refer to 11.24.2 Class-specific Requests of usb_20 */ + EXT_HUB_STAGE_FAILURE /**< Device has internal error and requires handling */ +} ext_hub_stage_t; + +const char *const ext_hub_stage_strings[] = { + "IDLE", + "GET_DEVICE_STATUS", + "CHECK_DEVICE_STATUS", + "GET_HUB_DESCRIPTOR", + "CHECK_HUB_DESCRIPTOR", + "GET_HUB_STATUS", + "CHECK_HUB_STATUS", + "PORT_FEATURE", + "PORT_STATUS_REQUEST", + "FAILURE" +}; + +/** + * @brief Device action flags + */ +typedef enum { + DEV_ACTION_EP0_COMPLETE = (1 << 1), /**< Device complete one of stages, requires handling */ + DEV_ACTION_EP1_FLUSH = (1 << 2), /**< Device's Interrupt EP needs to be flushed */ + DEV_ACTION_EP1_DEQUEUE = (1 << 3), /**< Device's Interrupt EP needs to be dequeued */ + DEV_ACTION_EP1_CLEAR = (1 << 4), /**< Device's Interrupt EP needs to be cleared */ + DEV_ACTION_REQ = (1 << 5), /**< Device has new actions and required handling */ + DEV_ACTION_ERROR = (1 << 6), /**< Device encounters an error */ + DEV_ACTION_GONE = (1 << 7), /**< Device was gone */ + DEV_ACTION_RELEASE = (1 << 8), /**< Device was released */ + DEV_ACTION_FREE = (1 << 9), /**< Device should be freed */ +} dev_action_t; + +typedef struct ext_hub_s ext_hub_dev_t; + +/** + * @brief External Hub device configuration parameters for device allocation + */ +typedef struct { + usb_device_handle_t dev_hdl; /**< Device's handle */ + uint8_t dev_addr; /**< Device's bus address */ + const usb_intf_desc_t *iface_desc; /**< Device's Interface Descriptor pointer */ + const usb_ep_desc_t *ep_in_desc; /**< Device's IN Endpoint Descriptor pointer */ +} device_config_t; + +struct ext_hub_s { + struct { + TAILQ_ENTRY(ext_hub_s) tailq_entry; + union { + struct { + uint32_t in_pending_list: 1; /**< Device is in pending list */ + uint32_t waiting_free: 1; /**< Device waiting to be freed */ + uint32_t is_gone: 1; /**< Device is gone */ + uint32_t reserved29: 29; /**< Reserved */ + }; + uint32_t val; /**< Device's flags value */ + } flags; + uint32_t action_flags; /**< Device's action flags */ + ext_hub_state_t state; /**< Device's state */ + ext_hub_stage_t stage; /**< Device's stage */ + } dynamic; /**< Dynamic members require a critical section */ + + struct { + // For optimisation & debug only + uint8_t iface_num; /**< Device's bInterfaceNum */ + // Driver purpose + uint8_t dev_addr; /**< Device's bus address */ + usb_device_handle_t dev_hdl; /**< Device's handle */ + urb_t *ctrl_urb; /**< Device's Control pipe transfer URB */ + urb_t *in_urb; /**< Device's Interrupt pipe URB */ + usbh_ep_handle_t ep_in_hdl; /**< Device's Interrupt EP handle */ + + usb_hub_descriptor_t *hub_desc; /**< Device's Hub descriptor pointer. Could be NULL when not requested */ + uint8_t maxchild; /**< Number of ports. Could be 0 for some Hubs. */ + ext_port_hdl_t *ports; /**< Flexible array of Ports. Could be NULL, when maxchild is 0 */ + } constant; /**< Constant members. Do not change after installation thus do not require a critical section or mutex */ +}; + +typedef struct { + struct { + TAILQ_HEAD(ext_hubs, ext_hub_s) ext_hubs_tailq; /**< Idle tailq */ + TAILQ_HEAD(ext_hubs_cb, ext_hub_s) ext_hubs_pending_tailq; /**< Pending tailq */ + } dynamic; /**< Dynamic members require a critical section */ + + struct { + ext_hub_cb_t proc_req_cb; /**< Process callback */ + void *proc_req_cb_arg; /**< Process callback argument */ + const ext_hub_port_driver_t* port_driver; /**< External Port Driver */ + } constant; /**< Constant members. Do not change after installation thus do not require a critical section or mutex */ +} ext_hub_driver_t; + +static ext_hub_driver_t *p_ext_hub_driver = NULL; +static portMUX_TYPE ext_hub_driver_lock = portMUX_INITIALIZER_UNLOCKED; + +const char *EXT_HUB_TAG = "EXT_HUB"; + +// ----------------------------------------------------------------------------- +// ------------------------------- Helpers ------------------------------------- +// ----------------------------------------------------------------------------- + +#define EXT_HUB_ENTER_CRITICAL() portENTER_CRITICAL(&ext_hub_driver_lock) +#define EXT_HUB_EXIT_CRITICAL() portEXIT_CRITICAL(&ext_hub_driver_lock) +#define EXT_HUB_ENTER_CRITICAL_SAFE() portENTER_CRITICAL_SAFE(&ext_hub_driver_lock) +#define EXT_HUB_EXIT_CRITICAL_SAFE() portEXIT_CRITICAL_SAFE(&ext_hub_driver_lock) + +#define EXT_HUB_CHECK(cond, ret_val) ({ \ + if (!(cond)) { \ + return (ret_val); \ + } \ +}) +#define EXT_HUB_CHECK_FROM_CRIT(cond, ret_val) ({ \ + if (!(cond)) { \ + EXT_HUB_EXIT_CRITICAL(); \ + return ret_val; \ + } \ +}) + +// ----------------------------------------------------------------------------- +// ----------------------- Forward declaration --------------------------------- +// ----------------------------------------------------------------------------- +static bool _device_set_actions(ext_hub_dev_t *ext_hub_dev, uint32_t action_flags); +static void device_disable(ext_hub_dev_t *ext_hub_dev); +static void device_error(ext_hub_dev_t *ext_hub_dev); +static void device_status_change_handle(ext_hub_dev_t *ext_hub_dev, const uint8_t* data, const int length); + +// ----------------------------------------------------------------------------- +// ---------------------- Callbacks (implementation) --------------------------- +// ----------------------------------------------------------------------------- + +static bool interrupt_pipe_cb(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event, void *user_arg, bool in_isr) +{ + uint32_t action_flags; + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)user_arg; + + switch (ep_event) { + case USBH_EP_EVENT_URB_DONE: { + // A interrupt transfer completed on EP1's pipe . We need to dequeue it + action_flags = DEV_ACTION_EP1_DEQUEUE; + break; + case USBH_EP_EVENT_ERROR_XFER: + case USBH_EP_EVENT_ERROR_URB_NOT_AVAIL: + case USBH_EP_EVENT_ERROR_OVERFLOW: + // EP1's pipe has encountered an error. We need to retire all URBs, dequeue them, then make the pipe active again + action_flags = DEV_ACTION_EP1_FLUSH | + DEV_ACTION_EP1_DEQUEUE | + DEV_ACTION_EP1_CLEAR; + if (in_isr) { + ESP_EARLY_LOGE(EXT_HUB_TAG, "Device %d EP1 Error", ext_hub_dev->constant.dev_addr); + } else { + ESP_LOGE(EXT_HUB_TAG, "Device %d EP1 Error", ext_hub_dev->constant.dev_addr); + } + break; + case USBH_EP_EVENT_ERROR_STALL: + // EP1's pipe encountered a "protocol stall". We just need to dequeue URBs then make the pipe active again + action_flags = DEV_ACTION_EP1_DEQUEUE | DEV_ACTION_EP1_CLEAR; + if (in_isr) { + ESP_EARLY_LOGE(EXT_HUB_TAG, "Device %d EP1 STALL", ext_hub_dev->constant.dev_addr); + } else { + ESP_LOGE(EXT_HUB_TAG, "Device %d EP1 STALL", ext_hub_dev->constant.dev_addr); + } + break; + } + default: + action_flags = 0; + break; + } + + EXT_HUB_ENTER_CRITICAL_SAFE(); + bool call_proc_req_cb = _device_set_actions(ext_hub_dev, action_flags); + EXT_HUB_EXIT_CRITICAL_SAFE(); + + bool yield = false; + if (call_proc_req_cb) { + yield = p_ext_hub_driver->constant.proc_req_cb(in_isr, p_ext_hub_driver->constant.proc_req_cb_arg); + } + return yield; +} + +/** + * @brief Control transfer completion callback + * + * Is called by lower logic when transfer is completed with or without error + * + * @param[in] ctrl_xfer Pointer to a transfer buffer + */ +static void control_transfer_complete_cb(usb_transfer_t *ctrl_xfer) +{ + bool call_proc_req_cb = false; + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *) ctrl_xfer->context; + + EXT_HUB_ENTER_CRITICAL(); + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_EP0_COMPLETE); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +static void interrupt_transfer_complete_cb(usb_transfer_t *intr_xfer) +{ + assert(intr_xfer); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)intr_xfer->context; + assert(ext_hub_dev); + + switch (intr_xfer->status) { + case USB_TRANSFER_STATUS_COMPLETED: + ESP_LOG_BUFFER_HEXDUMP(EXT_HUB_TAG, intr_xfer->data_buffer, intr_xfer->actual_num_bytes, ESP_LOG_VERBOSE); + device_status_change_handle(ext_hub_dev, intr_xfer->data_buffer, intr_xfer->actual_num_bytes); + break; + case USB_TRANSFER_STATUS_NO_DEVICE: + // Device was removed, nothing to do + break; + case USB_TRANSFER_STATUS_CANCELED: + // Cancellation due to USB Host uninstall routine + device_disable(ext_hub_dev); + break; + default: + // Any other error + ESP_LOGE(EXT_HUB_TAG, "[%d] Interrupt transfer failed, status %d", ext_hub_dev->constant.dev_addr, intr_xfer->status); + device_error(ext_hub_dev); + break; + } + +} + +// ----------------------------------------------------------------------------- +// --------------------------- Internal Logic --------------------------------- +// ----------------------------------------------------------------------------- + +static bool _device_set_actions(ext_hub_dev_t *ext_hub_dev, uint32_t action_flags) +{ + /* + THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION + */ + if (action_flags == 0) { + return false; + } + bool call_proc_req_cb; + // Check if device is already on the callback list + if (!ext_hub_dev->dynamic.flags.in_pending_list) { + // Move device form idle device list to callback device list + TAILQ_REMOVE(&p_ext_hub_driver->dynamic.ext_hubs_tailq, ext_hub_dev, dynamic.tailq_entry); + TAILQ_INSERT_TAIL(&p_ext_hub_driver->dynamic.ext_hubs_pending_tailq, ext_hub_dev, dynamic.tailq_entry); + ext_hub_dev->dynamic.action_flags |= action_flags; + ext_hub_dev->dynamic.flags.in_pending_list = 1; + call_proc_req_cb = true; + } else { + // The device is already on the callback list, thus a processing request is already pending. + ext_hub_dev->dynamic.action_flags |= action_flags; + call_proc_req_cb = false; + } + return call_proc_req_cb; +} + +static esp_err_t device_enable_int_ep(ext_hub_dev_t *ext_hub_dev) +{ + esp_err_t ret = ESP_OK; + ret = usbh_ep_enqueue_urb(ext_hub_dev->constant.ep_in_hdl, ext_hub_dev->constant.in_urb); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Failed to submit in urb (%#x)", ret); + return ret; + } + return ret; +} + +static void device_has_changed(ext_hub_dev_t *ext_hub_dev) +{ + // TODO: IDF-10053 Hub status change handling + // After getting the IRQ about Hub status change we need to request status + // device_get_status(ext_hub_dev); + ESP_LOGW(EXT_HUB_TAG, "Hub status change has not been implemented yet"); + device_enable_int_ep(ext_hub_dev); +} + +// Figure 11-22. Hub and Port Status Change Bitmap +static void device_status_change_handle(ext_hub_dev_t *ext_hub_dev, const uint8_t* data, const int length) +{ + uint8_t port_idx = 0; + uint8_t max_port_num = (sizeof(uint8_t) * 8) - 1; // Maximal Port number in one uint8_t byte + // Hub status change + if (data[0] & EXT_HUB_STATUS_CHANGE_FLAG) { + device_has_changed(ext_hub_dev); + } + // Ports status change + for (uint8_t i = 0; i < length; i++) { + for (uint8_t j = 0; j < max_port_num; j++) { + if (data[i] & (EXT_HUB_STATUS_PORT1_CHANGE_FLAG << j)) { + // Notify Hub driver + port_idx = (j + (i * max_port_num)); + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->get_status(ext_hub_dev->constant.ports[port_idx]); + } + } + } + } +} + +static void device_disable(ext_hub_dev_t *ext_hub_dev) +{ + bool call_proc_req_cb = false; + + ESP_LOGD(EXT_HUB_TAG, "[%d] Device disable", ext_hub_dev->constant.dev_addr); + + if (ext_hub_dev->dynamic.state == EXT_HUB_STATE_RELEASED || ext_hub_dev->dynamic.flags.is_gone) { + ESP_LOGD(EXT_HUB_TAG, "Device in release state or already gone"); + return; + } + + // Mark all Ports are disable and then gone + for (uint8_t i = 0; i < ext_hub_dev->constant.maxchild; i++) { + if (p_ext_hub_driver->constant.port_driver) { + // TODO: IDF-10054 Hubs should disable their ports power + // Meanwhile, mark the port as gone + p_ext_hub_driver->constant.port_driver->gone(ext_hub_dev->constant.ports[i]); + } + } + + // Close the device + ESP_ERROR_CHECK(usbh_dev_close(ext_hub_dev->constant.dev_hdl)); + + EXT_HUB_ENTER_CRITICAL(); + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_FREE); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +static void device_error(ext_hub_dev_t *ext_hub_dev) +{ + bool call_proc_req_cb = false; + + EXT_HUB_ENTER_CRITICAL(); + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_ERROR); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +static void device_release(ext_hub_dev_t *ext_hub_dev) +{ + bool call_proc_req_cb = false; + + ESP_LOGD(EXT_HUB_TAG, "[%d] Device release", ext_hub_dev->constant.dev_addr); + + // Mark all Ports are disable and then gone + for (uint8_t i = 0; i < ext_hub_dev->constant.maxchild; i++) { + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->gone(ext_hub_dev->constant.ports[i]); + } + } + + // Release IN EP + ESP_ERROR_CHECK(usbh_ep_command(ext_hub_dev->constant.ep_in_hdl, USBH_EP_CMD_HALT)); + + // Close the device + ESP_ERROR_CHECK(usbh_dev_close(ext_hub_dev->constant.dev_hdl)); + + EXT_HUB_ENTER_CRITICAL(); + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_FREE); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +static esp_err_t device_alloc_desc(ext_hub_dev_t *ext_hub_hdl, const usb_hub_descriptor_t *hub_desc) +{ + // Allocate memory to store the configuration descriptor + usb_hub_descriptor_t *desc = heap_caps_malloc(hub_desc->bDescLength, MALLOC_CAP_DEFAULT); // Buffer to copy over full configuration descriptor (wTotalLength) + if (desc == NULL) { + return ESP_ERR_NO_MEM; + } + // Copy the hub descriptor + memcpy(desc, hub_desc, hub_desc->bDescLength); + // Assign the hub descriptor to the device object + assert(ext_hub_hdl->constant.hub_desc == NULL); + ext_hub_hdl->constant.hub_desc = desc; + return ESP_OK; +} + +static esp_err_t device_alloc(device_config_t *config, ext_hub_dev_t **ext_hub_dev) +{ + esp_err_t ret; + urb_t *ctrl_urb = NULL; + urb_t *in_urb = NULL; + +#if !ENABLE_MULTIPLE_HUBS + usb_device_info_t dev_info; + ESP_ERROR_CHECK(usbh_dev_get_info(config->dev_hdl, &dev_info)); + if (dev_info.parent.dev_hdl) { + ESP_LOGW(EXT_HUB_TAG, "Multiple Hubs not supported, use menuconfig to enable feature"); + ret = ESP_ERR_NOT_SUPPORTED; + goto fail; + } +#endif // ENABLE_MULTIPLE_HUBS + + ext_hub_dev_t *hub_dev = heap_caps_calloc(1, sizeof(ext_hub_dev_t), MALLOC_CAP_DEFAULT); + + if (hub_dev == NULL) { + ESP_LOGE(EXT_HUB_TAG, "Unable to allocate device"); + ret = ESP_ERR_NO_MEM; + goto fail; + } + + // Allocate Control transfer URB + ctrl_urb = urb_alloc(sizeof(usb_setup_packet_t) + EXT_HUB_CTRL_TRANSFER_MAX_DATA_LEN, 0); + if (ctrl_urb == NULL) { + ESP_LOGE(EXT_HUB_TAG, "Unable to allocate Control URB"); + ret = ESP_ERR_NO_MEM; + goto ctrl_urb_fail; + } + + in_urb = urb_alloc(config->ep_in_desc->wMaxPacketSize, 0); + // Allocate Interrupt transfer URB + if (in_urb == NULL) { + ESP_LOGE(EXT_HUB_TAG, "Unable to allocate Interrupt URB"); + ret = ESP_ERR_NO_MEM; + goto in_urb_fail; + } + + usbh_ep_handle_t ep_hdl; + usbh_ep_config_t ep_config = { + .bInterfaceNumber = config->iface_desc->bInterfaceNumber, + .bAlternateSetting = config->iface_desc->bAlternateSetting, + .bEndpointAddress = config->ep_in_desc->bEndpointAddress, + .ep_cb = interrupt_pipe_cb, + .ep_cb_arg = (void *)hub_dev, + .context = (void *)hub_dev, + }; + + ret = usbh_ep_alloc(config->dev_hdl, &ep_config, &ep_hdl); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Endpoint allocation failure (%#x)", ret); + goto ep_fail; + } + // Configure Control transfer URB + ctrl_urb->usb_host_client = (void *) p_ext_hub_driver; + ctrl_urb->transfer.callback = control_transfer_complete_cb; + ctrl_urb->transfer.context = (void *) hub_dev; + + // Client is a memory address of the p_ext_hub_driver driver object + in_urb->usb_host_client = (void *) p_ext_hub_driver; + in_urb->transfer.callback = interrupt_transfer_complete_cb; + in_urb->transfer.context = (void *) hub_dev; + in_urb->transfer.num_bytes = config->ep_in_desc->wMaxPacketSize; + + // Save constant parameters + hub_dev->constant.ep_in_hdl = ep_hdl; + hub_dev->constant.ctrl_urb = ctrl_urb; + hub_dev->constant.in_urb = in_urb; + hub_dev->constant.dev_hdl = config->dev_hdl; + hub_dev->constant.dev_addr = config->dev_addr; + hub_dev->constant.iface_num = config->iface_desc->bInterfaceNumber; + // We will update number of ports during Hub Descriptor handling stage + hub_dev->constant.maxchild = 0; + + hub_dev->dynamic.flags.val = 0; + hub_dev->dynamic.state = EXT_HUB_STATE_ATTACHED; + hub_dev->dynamic.stage = EXT_HUB_STAGE_IDLE; + + EXT_HUB_ENTER_CRITICAL(); + TAILQ_INSERT_TAIL(&p_ext_hub_driver->dynamic.ext_hubs_tailq, hub_dev, dynamic.tailq_entry); + EXT_HUB_EXIT_CRITICAL(); + + ESP_LOGD(EXT_HUB_TAG, "[%d] New device (iface %d)", config->dev_addr, hub_dev->constant.iface_num); + + *ext_hub_dev = hub_dev; + return ret; + +ep_fail: + urb_free(in_urb); +in_urb_fail: + urb_free(ctrl_urb); +ctrl_urb_fail: + heap_caps_free(hub_dev); +fail: + return ret; +} + +static esp_err_t device_configure(ext_hub_dev_t *ext_hub_dev) +{ + EXT_HUB_CHECK(ext_hub_dev->constant.hub_desc != NULL, ESP_ERR_INVALID_STATE); + usb_hub_descriptor_t *hub_desc = ext_hub_dev->constant.hub_desc; + + ESP_LOGD(EXT_HUB_TAG, "[%d] Device configure (iface %d)", + ext_hub_dev->constant.dev_addr, + ext_hub_dev->constant.iface_num); + + if (hub_desc->wHubCharacteristics.compound) { + ESP_LOGD(EXT_HUB_TAG, "\tCompound device"); + } else { + ESP_LOGD(EXT_HUB_TAG, "\tStandalone HUB"); + } + + ESP_LOGD(EXT_HUB_TAG, "\t%d external port%s", + ext_hub_dev->constant.hub_desc->bNbrPorts, + (ext_hub_dev->constant.hub_desc->bNbrPorts == 1) ? "" : "s"); + + switch (hub_desc->wHubCharacteristics.power_switching) { + case USB_W_HUB_CHARS_PORT_PWR_CTRL_NO: + ESP_LOGD(EXT_HUB_TAG, "\tNo power switching (usb 1.0)"); + break; + case USB_W_HUB_CHARS_PORT_PWR_CTRL_INDV: + ESP_LOGD(EXT_HUB_TAG, "\tIndividual port power switching"); + break; + default: + // USB_W_HUB_CHARS_PORT_PWR_CTRL_ALL + ESP_LOGD(EXT_HUB_TAG, "\tAll ports power at once"); + break; + } + + switch (hub_desc->wHubCharacteristics.ovr_current_protect) { + case USB_W_HUB_CHARS_PORT_OVER_CURR_NO: + ESP_LOGD(EXT_HUB_TAG, "\tNo over-current protection"); + break; + case USB_W_HUB_CHARS_PORT_OVER_CURR_INDV: + ESP_LOGD(EXT_HUB_TAG, "\tIndividual port over-current protection"); + break; + default: + // USB_W_HUB_CHARS_PORT_OVER_CURR_ALL + ESP_LOGD(EXT_HUB_TAG, "\tGlobal over-current protection"); + break; + } + + if (hub_desc->wHubCharacteristics.indicator_support) { + ESP_LOGD(EXT_HUB_TAG, "\tPort indicators are supported"); + } + + ESP_LOGD(EXT_HUB_TAG, "\tPower on to power good time: %dms", hub_desc->bPwrOn2PwrGood * 2); + ESP_LOGD(EXT_HUB_TAG, "\tMaximum current: %d mA", hub_desc->bHubContrCurrent); + + // Create External Port flexible array + ext_hub_dev->constant.ports = heap_caps_calloc(ext_hub_dev->constant.hub_desc->bNbrPorts, sizeof(ext_port_hdl_t), MALLOC_CAP_DEFAULT); + if (ext_hub_dev->constant.ports == NULL) { + ESP_LOGE(EXT_HUB_TAG, "Ports allocation err"); + return ESP_ERR_NO_MEM; + } + + // Update device port amount + ext_hub_dev->constant.maxchild = ext_hub_dev->constant.hub_desc->bNbrPorts; + + // Create port and add it to pending list + for (uint8_t i = 0; i < ext_hub_dev->constant.maxchild; i++) { + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->new (NULL, (void**) &ext_hub_dev->constant.ports[i]); + } + } + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.state = EXT_HUB_STATE_CONFIGURED; + EXT_HUB_EXIT_CRITICAL(); + + return ESP_OK; +} + +static void device_free(ext_hub_dev_t *ext_hub_dev) +{ + ESP_LOGD(EXT_HUB_TAG, "[%d] Freeing device", ext_hub_dev->constant.dev_addr); + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.flags.waiting_free = 0; + TAILQ_REMOVE(&p_ext_hub_driver->dynamic.ext_hubs_tailq, ext_hub_dev, dynamic.tailq_entry); + EXT_HUB_EXIT_CRITICAL(); + + // Free ports + for (uint8_t i = 0; i < ext_hub_dev->constant.maxchild; i++) { + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->free(ext_hub_dev->constant.ports[i]); + } + } + + if (ext_hub_dev->constant.hub_desc) { + heap_caps_free(ext_hub_dev->constant.hub_desc); + } + if (ext_hub_dev->constant.ports) { + heap_caps_free(ext_hub_dev->constant.ports); + } + + ESP_ERROR_CHECK(usbh_ep_free(ext_hub_dev->constant.ep_in_hdl)); + urb_free(ext_hub_dev->constant.ctrl_urb); + urb_free(ext_hub_dev->constant.in_urb); + + heap_caps_free(ext_hub_dev); +} + +static esp_err_t get_dev_by_hdl(usb_device_handle_t dev_hdl, ext_hub_dev_t **ext_hub_hdl) +{ + esp_err_t ret = ESP_OK; + // Go through the Hubs lists to find the hub with the specified device address + ext_hub_dev_t *found_hub = NULL; + ext_hub_dev_t *hub = NULL; + + EXT_HUB_ENTER_CRITICAL(); + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_pending_tailq, dynamic.tailq_entry) { + if (hub->constant.dev_hdl == dev_hdl) { + found_hub = hub; + goto exit; + } + } + + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_tailq, dynamic.tailq_entry) { + if (hub->constant.dev_hdl == dev_hdl) { + found_hub = hub; + goto exit; + } + } + +exit: + if (found_hub == NULL) { + ret = ESP_ERR_NOT_FOUND; + } + EXT_HUB_EXIT_CRITICAL(); + + *ext_hub_hdl = found_hub; + return ret; +} + +static esp_err_t get_dev_by_addr(uint8_t dev_addr, ext_hub_dev_t **ext_hub_hdl) +{ + esp_err_t ret = ESP_OK; + // Go through the Hubs lists to find the Hub with the specified device address + ext_hub_dev_t *found_hub = NULL; + ext_hub_dev_t *hub = NULL; + + EXT_HUB_ENTER_CRITICAL(); + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_pending_tailq, dynamic.tailq_entry) { + if (hub->constant.dev_addr == dev_addr) { + found_hub = hub; + goto exit; + } + } + + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_tailq, dynamic.tailq_entry) { + if (hub->constant.dev_addr == dev_addr) { + found_hub = hub; + goto exit; + } + } + +exit: + if (found_hub == NULL) { + ret = ESP_ERR_NOT_FOUND; + } + EXT_HUB_EXIT_CRITICAL(); + + *ext_hub_hdl = found_hub; + return ret; +} + +// ----------------------------------------------------------------------------- +// -------------------------- Device handling --------------------------------- +// ----------------------------------------------------------------------------- + +static bool handle_hub_descriptor(ext_hub_dev_t *ext_hub_dev) +{ + esp_err_t ret; + bool pass; + usb_transfer_t *ctrl_xfer = &ext_hub_dev->constant.ctrl_urb->transfer; + const usb_hub_descriptor_t *hub_desc = (const usb_hub_descriptor_t *)(ctrl_xfer->data_buffer + sizeof(usb_setup_packet_t)); + + if (ctrl_xfer->status != USB_TRANSFER_STATUS_COMPLETED) { + ESP_LOGE(EXT_HUB_TAG, "Bad transfer status %d: stage=%d", ctrl_xfer->status, ext_hub_dev->dynamic.stage); + return false; + } + + ESP_LOG_BUFFER_HEXDUMP(EXT_HUB_TAG, ctrl_xfer->data_buffer, ctrl_xfer->actual_num_bytes, ESP_LOG_VERBOSE); + + ret = device_alloc_desc(ext_hub_dev, hub_desc); + if (ret != ESP_OK) { + pass = false; + goto exit; + } + + ret = device_configure(ext_hub_dev); + if (ret != ESP_OK) { + pass = false; + goto exit; + } + + pass = true; +exit: + return pass; +} + +static bool handle_device_status(ext_hub_dev_t *ext_hub_dev) +{ + usb_transfer_t *ctrl_xfer = &ext_hub_dev->constant.ctrl_urb->transfer; + const usb_device_status_t *dev_status = (const usb_device_status_t *)(ctrl_xfer->data_buffer + sizeof(usb_setup_packet_t)); + + ESP_LOGD(EXT_HUB_TAG, "[%d] Device status: ", ext_hub_dev->constant.dev_addr); + ESP_LOGD(EXT_HUB_TAG, "\tPower: %s", dev_status->self_powered ? "self-powered" : "bus-powered"); + ESP_LOGD(EXT_HUB_TAG, "\tRemoteWakeup: %s", dev_status->remote_wakeup ? "yes" : "no"); + + if (dev_status->remote_wakeup) { + // Device in remote_wakeup, we need send command Clear Device Feature: USB_W_VALUE_FEATURE_DEVICE_REMOTE_WAKEUP + // HEX codes of command: 00 01 01 00 00 00 00 00 + // TODO: IDF-10055 Hub Support remote_wakeup feature + ESP_LOGW(EXT_HUB_TAG, "Remote Wakeup feature has not been implemented yet"); + } + return true; +} + +static bool handle_hub_status(ext_hub_dev_t *ext_hub_dev) +{ + usb_transfer_t *ctrl_xfer = &ext_hub_dev->constant.ctrl_urb->transfer; + const usb_hub_status_t *hub_status = (const usb_hub_status_t *)(ctrl_xfer->data_buffer + sizeof(usb_setup_packet_t)); + + ESP_LOGD(EXT_HUB_TAG, "[%d] Hub status: ", ext_hub_dev->constant.dev_addr); + ESP_LOGD(EXT_HUB_TAG, "\tExternal power supply: %s", hub_status->wHubStatus.HUB_LOCAL_POWER ? "yes" : "no"); + ESP_LOGD(EXT_HUB_TAG, "\tOvercurrent: %s", hub_status->wHubStatus.HUB_OVER_CURRENT ? "yes" : "no"); + + if (hub_status->wHubStatus.HUB_OVER_CURRENT) { + ESP_LOGE(EXT_HUB_TAG, "Device has overcurrent!"); + // Hub has an overcurrent, we need to disable all port and/or disable parent port + // TODO: IDF-10056 Hubs overcurrent handling + ESP_LOGW(EXT_HUB_TAG, "Feature has not been implemented yet"); + return false; + } + + return true; +} + +static bool device_control_request(ext_hub_dev_t *ext_hub_dev) +{ + esp_err_t ret; + usb_transfer_t *transfer = &ext_hub_dev->constant.ctrl_urb->transfer; + + switch (ext_hub_dev->dynamic.stage) { + case EXT_HUB_STAGE_GET_DEVICE_STATUS: + USB_SETUP_PACKET_INIT_GET_STATUS((usb_setup_packet_t *)transfer->data_buffer); + transfer->num_bytes = sizeof(usb_setup_packet_t) + sizeof(usb_device_status_t); + break; + case EXT_HUB_STAGE_GET_HUB_DESCRIPTOR: + USB_SETUP_PACKET_INIT_GET_HUB_DESCRIPTOR((usb_setup_packet_t *)transfer->data_buffer); + transfer->num_bytes = sizeof(usb_setup_packet_t) + sizeof(usb_hub_descriptor_t); + break; + case EXT_HUB_STAGE_GET_HUB_STATUS: + USB_SETUP_PACKET_INIT_GET_HUB_STATUS((usb_setup_packet_t *)transfer->data_buffer); + transfer->num_bytes = sizeof(usb_setup_packet_t) + sizeof(usb_hub_status_t); + break; + default: + // Should never occur + abort(); + break; + } + + ret = usbh_dev_submit_ctrl_urb(ext_hub_dev->constant.dev_hdl, ext_hub_dev->constant.ctrl_urb); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Failed to submit ctrl urb, error %#x", ret); + return false; + } + + return true; +} + +static bool device_control_response_handling(ext_hub_dev_t *ext_hub_dev) +{ + bool stage_pass = false; + + switch (ext_hub_dev->dynamic.stage) { + case EXT_HUB_STAGE_CHECK_DEVICE_STATUS: + stage_pass = handle_device_status(ext_hub_dev); + break; + case EXT_HUB_STAGE_CHECK_HUB_DESCRIPTOR: + stage_pass = handle_hub_descriptor(ext_hub_dev); + break; + case EXT_HUB_STAGE_CHECK_HUB_STATUS: + stage_pass = handle_hub_status(ext_hub_dev); + break; + default: + // Should never occur + abort(); + break; + } + + return stage_pass; +} + +static bool stage_need_process(ext_hub_stage_t stage) +{ + bool need_process_cb = false; + + switch (stage) { + // Stages, required control transfer + case EXT_HUB_STAGE_GET_DEVICE_STATUS: + case EXT_HUB_STAGE_GET_HUB_DESCRIPTOR: + case EXT_HUB_STAGE_GET_HUB_STATUS: + // Error stage + case EXT_HUB_STAGE_FAILURE: + need_process_cb = true; + break; + default: + break; + } + + return need_process_cb; +} + +// return +// true - next stage requires the processing +// false - terminal stage +static bool device_set_next_stage(ext_hub_dev_t *ext_hub_dev, bool last_stage_pass) +{ + bool need_process_cb; + ext_hub_stage_t last_stage = ext_hub_dev->dynamic.stage; + ext_hub_stage_t next_stage; + + if (last_stage_pass) { + ESP_LOGD(EXT_HUB_TAG, "Stage %s OK", ext_hub_stage_strings[last_stage]); + if (last_stage == EXT_HUB_STAGE_GET_DEVICE_STATUS || + last_stage == EXT_HUB_STAGE_GET_HUB_DESCRIPTOR || + last_stage == EXT_HUB_STAGE_GET_HUB_STATUS) { + // Simply increment to get the next stage + next_stage = last_stage + 1; + } else { + // Terminal stages, move to IDLE + next_stage = EXT_HUB_STAGE_IDLE; + } + } else { + ESP_LOGE(EXT_HUB_TAG, "Stage %s FAILED", ext_hub_stage_strings[last_stage]); + // These stages cannot fail + assert(last_stage != EXT_HUB_STAGE_PORT_FEATURE || + last_stage != EXT_HUB_STAGE_PORT_STATUS_REQUEST); + + next_stage = EXT_HUB_STAGE_FAILURE; + } + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = next_stage; + need_process_cb = stage_need_process(next_stage); + EXT_HUB_EXIT_CRITICAL(); + + return need_process_cb; +} + +static void handle_port_feature(ext_hub_dev_t *ext_hub_dev) +{ + usb_transfer_t *ctrl_xfer = &ext_hub_dev->constant.ctrl_urb->transfer; + uint8_t port_num = USB_SETUP_PACKET_GET_PORT((usb_setup_packet_t *)ctrl_xfer->data_buffer); + uint8_t port_idx = port_num - 1; + + assert(port_idx < ext_hub_dev->constant.maxchild); + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->get_status(ext_hub_dev->constant.ports[port_idx]); + } +} + +static void handle_port_status(ext_hub_dev_t *ext_hub_dev) +{ + usb_transfer_t *ctrl_xfer = &ext_hub_dev->constant.ctrl_urb->transfer; + uint8_t port_num = USB_SETUP_PACKET_GET_PORT((usb_setup_packet_t *)ctrl_xfer->data_buffer); + uint8_t port_idx = port_num - 1; + const usb_port_status_t *new_status = (const usb_port_status_t *)(ctrl_xfer->data_buffer + sizeof(usb_setup_packet_t)); + + assert(port_idx < ext_hub_dev->constant.maxchild); + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->set_status(ext_hub_dev->constant.ports[port_idx], new_status); + } +} + +static void handle_device(ext_hub_dev_t *ext_hub_dev) +{ + bool call_proc_req_cb; + bool stage_pass = false; + // FSM for external Hub + switch (ext_hub_dev->dynamic.stage) { + case EXT_HUB_STAGE_IDLE: + break; + case EXT_HUB_STAGE_GET_DEVICE_STATUS: + case EXT_HUB_STAGE_GET_HUB_DESCRIPTOR: + case EXT_HUB_STAGE_GET_HUB_STATUS: + stage_pass = device_control_request(ext_hub_dev); + break; + case EXT_HUB_STAGE_CHECK_HUB_DESCRIPTOR: + stage_pass = device_control_response_handling(ext_hub_dev); + break; + case EXT_HUB_STAGE_PORT_FEATURE: + handle_port_feature(ext_hub_dev); + stage_pass = true; + break; + case EXT_HUB_STAGE_PORT_STATUS_REQUEST: + handle_port_status(ext_hub_dev); + stage_pass = true; + break; + case EXT_HUB_STAGE_FAILURE: + ESP_LOGW(EXT_HUB_TAG, "External Hub device failure handling has not been implemented yet"); + // device_error(ext_hub_dev); + break; + default: + // Should never occur + abort(); + break; + } + + call_proc_req_cb = device_set_next_stage(ext_hub_dev, stage_pass); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +static void handle_ep1_flush(ext_hub_dev_t *ext_hub_dev) +{ + ESP_ERROR_CHECK(usbh_ep_command(ext_hub_dev->constant.ep_in_hdl, USBH_EP_CMD_HALT)); + ESP_ERROR_CHECK(usbh_ep_command(ext_hub_dev->constant.ep_in_hdl, USBH_EP_CMD_FLUSH)); +} + +static void handle_ep1_dequeue(ext_hub_dev_t *ext_hub_dev) +{ + // Dequeue all URBs and run their transfer callback + ESP_LOGD(EXT_HUB_TAG, "[%d] Interrupt dequeue", ext_hub_dev->constant.dev_addr); + urb_t *urb; + usbh_ep_dequeue_urb(ext_hub_dev->constant.ep_in_hdl, &urb); + while (urb != NULL) { + // Clear the transfer's in-flight flag to indicate the transfer is no longer in-flight + urb->usb_host_inflight = false; + urb->transfer.callback(&urb->transfer); + usbh_ep_dequeue_urb(ext_hub_dev->constant.ep_in_hdl, &urb); + } +} + +static void handle_ep1_clear(ext_hub_dev_t *ext_hub_dev) +{ + // We allow the pipe command to fail just in case the pipe becomes invalid mid command + usbh_ep_command(ext_hub_dev->constant.ep_in_hdl, USBH_EP_CMD_CLEAR); +} + +static void handle_error(ext_hub_dev_t *ext_hub_dev) +{ + // TODO: IDF-10057 Hub handling error + ESP_LOGW(EXT_HUB_TAG, "%s has not been implemented yet", __FUNCTION__); + device_disable(ext_hub_dev); +} + +static void handle_gone(ext_hub_dev_t *ext_hub_dev) +{ + bool call_proc_req_cb = false; + + // Set the flags + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.flags.waiting_free = 1; + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_FREE); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } +} + +// ----------------------------------------------------------------------------- +// ------------------------------ Driver --------------------------------------- +// ----------------------------------------------------------------------------- + +esp_err_t ext_hub_install(const ext_hub_config_t *config) +{ + esp_err_t ret; + ext_hub_driver_t *ext_hub_drv = heap_caps_calloc(1, sizeof(ext_hub_driver_t), MALLOC_CAP_DEFAULT); + EXT_HUB_CHECK(ext_hub_drv != NULL, ESP_ERR_NO_MEM); + + // Save callbacks + ext_hub_drv->constant.proc_req_cb = config->proc_req_cb; + ext_hub_drv->constant.proc_req_cb_arg = config->proc_req_cb_arg; + // Copy Port driver pointer + ext_hub_drv->constant.port_driver = config->port_driver; + + if (ext_hub_drv->constant.port_driver == NULL) { + ESP_LOGW(EXT_HUB_TAG, "Port Driver has not been installed"); + } + + TAILQ_INIT(&ext_hub_drv->dynamic.ext_hubs_tailq); + TAILQ_INIT(&ext_hub_drv->dynamic.ext_hubs_pending_tailq); + + EXT_HUB_ENTER_CRITICAL(); + if (p_ext_hub_driver != NULL) { + EXT_HUB_EXIT_CRITICAL(); + ret = ESP_ERR_INVALID_STATE; + goto fail; + } + p_ext_hub_driver = ext_hub_drv; + EXT_HUB_EXIT_CRITICAL(); + + ESP_LOGD(EXT_HUB_TAG, "Driver installed"); + return ESP_OK; + +fail: + heap_caps_free(ext_hub_drv); + return ret; +} + +esp_err_t ext_hub_uninstall(void) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_CHECK_FROM_CRIT(TAILQ_EMPTY(&p_ext_hub_driver->dynamic.ext_hubs_tailq), ESP_ERR_INVALID_STATE); + EXT_HUB_CHECK_FROM_CRIT(TAILQ_EMPTY(&p_ext_hub_driver->dynamic.ext_hubs_pending_tailq), ESP_ERR_INVALID_STATE); + ext_hub_driver_t *ext_hub_drv = p_ext_hub_driver; + p_ext_hub_driver = NULL; + EXT_HUB_EXIT_CRITICAL(); + + heap_caps_free(ext_hub_drv); + ESP_LOGD(EXT_HUB_TAG, "Driver uninstalled"); + return ESP_OK; +} + +void *ext_hub_get_client(void) +{ + bool driver_installed = false; + EXT_HUB_ENTER_CRITICAL(); + driver_installed = (p_ext_hub_driver != NULL); + EXT_HUB_EXIT_CRITICAL(); + return (driver_installed) ? (void*) p_ext_hub_driver : NULL; +} + +// ----------------------------------------------------------------------------- +// -------------------------- External Hub API --------------------------------- +// ----------------------------------------------------------------------------- + +esp_err_t ext_hub_get_handle(usb_device_handle_t dev_hdl, ext_hub_handle_t *ext_hub_hdl) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + return get_dev_by_hdl(dev_hdl, ext_hub_hdl); +} + +static esp_err_t find_first_intf_desc(const usb_config_desc_t *config_desc, device_config_t *hub_config) +{ + bool iface_found = false; + const usb_ep_desc_t *ep_in_desc = NULL; + + int offset = 0; + const usb_intf_desc_t *next_intf_desc = (const usb_intf_desc_t *)usb_parse_next_descriptor_of_type( + (const usb_standard_desc_t *)config_desc, + config_desc->wTotalLength, + USB_B_DESCRIPTOR_TYPE_INTERFACE, + &offset); + + while (next_intf_desc != NULL) { + if (iface_found) { + // TODO: IDF-10058 Hubs support interface selection (HS) + ESP_LOGW(EXT_HUB_TAG, "Device has several Interfaces, selection has not been implemented yet. Using first."); + break; + } + // Parse all interfaces + if (USB_CLASS_HUB == next_intf_desc->bInterfaceClass) { + // We have found the first interface descriptor with matching bInterfaceNumber +#if (OTG_HSPHY_INTERFACE != 0) + // TODO: IDF-10059 Hubs support multiple TT (HS) + if (next_intf_desc->bInterfaceProtocol != USB_B_DEV_PROTOCOL_HUB_HS_NO_TT) { + ESP_LOGD(EXT_HUB_TAG, "Transaction Translator:"); + ESP_LOGW(EXT_HUB_TAG, "Transaction Translator has not been implemented yet"); + } + + switch (next_intf_desc->bInterfaceProtocol) { + case USB_B_DEV_PROTOCOL_HUB_HS_NO_TT: + ESP_LOGD(EXT_HUB_TAG, "\tNo TT"); + break; + case USB_B_DEV_PROTOCOL_HUB_HS_SINGLE_TT: + ESP_LOGD(EXT_HUB_TAG, "\tSingle TT"); + break; + case USB_B_DEV_PROTOCOL_HUB_HS_MULTI_TT: + ESP_LOGD(EXT_HUB_TAG, "\tMulti TT"); + break; + default: + ESP_LOGE(EXT_HUB_TAG, "\tInterface Protocol (%#x) not supported", next_intf_desc->bInterfaceProtocol); + goto next_iface; + } +#else + if (next_intf_desc->bInterfaceProtocol != USB_B_DEV_PROTOCOL_HUB_FS) { + ESP_LOGE(EXT_HUB_TAG, "\tProtocol (%#x) not supported", next_intf_desc->bInterfaceProtocol); + goto next_iface; + } +#endif // OTG_HSPHY_INTERFACE != 0 + + // Hub Interface always should have only one Interrupt endpoint + if (next_intf_desc->bNumEndpoints != 1) { + ESP_LOGE(EXT_HUB_TAG, "Unexpected number of endpoints (%d)", next_intf_desc->bNumEndpoints); + goto next_iface; + } + // Get related IN EP + ep_in_desc = usb_parse_endpoint_descriptor_by_index(next_intf_desc, 0, config_desc->wTotalLength, &offset); + if (ep_in_desc == NULL) { + ESP_LOGE(EXT_HUB_TAG, "EP descriptor not found (iface=%d)", next_intf_desc->bInterfaceNumber); + goto next_iface; + } + + if (!USB_EP_DESC_GET_EP_DIR(ep_in_desc) || + (USB_EP_DESC_GET_XFERTYPE(ep_in_desc) != USB_TRANSFER_TYPE_INTR)) { + ESP_LOGE(EXT_HUB_TAG, "Interrupt EP not found (iface=%d)", next_intf_desc->bInterfaceNumber); + goto next_iface; + } + + // Interface found, fill the config + hub_config->iface_desc = next_intf_desc; + hub_config->ep_in_desc = ep_in_desc; + iface_found = true; + } + +next_iface: + next_intf_desc = (const usb_intf_desc_t *)usb_parse_next_descriptor_of_type( + (const usb_standard_desc_t *)next_intf_desc, + config_desc->wTotalLength, + USB_B_DESCRIPTOR_TYPE_INTERFACE, + &offset); + } + + return (iface_found) ? ESP_OK : ESP_ERR_NOT_FOUND; +} + +esp_err_t ext_hub_new_dev(uint8_t dev_addr) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + esp_err_t ret; + ext_hub_dev_t *hub_dev = NULL; + usb_device_handle_t dev_hdl = NULL; + const usb_config_desc_t *config_desc = NULL; + bool call_proc_req_cb = false; + + // Open device + ret = usbh_devs_open(dev_addr, &dev_hdl); + if (ret != ESP_OK) { + return ret; + } + + // Get Configuration Descriptor + ret = usbh_dev_get_config_desc(dev_hdl, &config_desc); + if (ret != ESP_OK) { + goto exit; + } + + // Find related Hub Interface descriptor + device_config_t hub_config = { + .dev_hdl = dev_hdl, + .dev_addr = dev_addr, + .iface_desc = NULL, + .ep_in_desc = NULL, + }; + + ret = find_first_intf_desc(config_desc, &hub_config); + if (ret != ESP_OK) { + goto exit; + } + + // Create External Hub device + ret = device_alloc(&hub_config, &hub_dev); + if (ret != ESP_OK) { + goto exit; + } + + EXT_HUB_ENTER_CRITICAL(); + hub_dev->dynamic.stage = EXT_HUB_STAGE_GET_HUB_DESCRIPTOR; + call_proc_req_cb = _device_set_actions(hub_dev, DEV_ACTION_REQ); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } + + return ret; + +exit: + ESP_ERROR_CHECK(usbh_dev_close(dev_hdl)); + return ret; +} + +esp_err_t ext_hub_dev_gone(uint8_t dev_addr) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + esp_err_t ret; + + ext_hub_dev_t *ext_hub_dev = NULL; + bool call_proc_req_cb = false; + + EXT_HUB_CHECK(dev_addr != 0, ESP_ERR_INVALID_ARG); + // Find device with dev_addr in the devices TAILQ + // TODO: IDF-10058 + // Release all devices by dev_addr + ret = get_dev_by_addr(dev_addr, &ext_hub_dev); + if (ret != ESP_OK) { + ESP_LOGD(EXT_HUB_TAG, "No device with address %d was found", dev_addr); + return ret; + } + + ESP_LOGE(EXT_HUB_TAG, "[%d] Device gone", ext_hub_dev->constant.dev_addr); + + for (uint8_t i = 0; i < ext_hub_dev->constant.maxchild; i++) { + if (p_ext_hub_driver->constant.port_driver) { + p_ext_hub_driver->constant.port_driver->gone(ext_hub_dev->constant.ports[i]); + } + } + + // Close the device + ESP_ERROR_CHECK(usbh_dev_close(ext_hub_dev->constant.dev_hdl)); + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.flags.is_gone = 1; + call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_GONE); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } + return ret; +} + +esp_err_t ext_hub_all_free(void) +{ + ext_hub_dev_t *hub = NULL; + bool call_proc_req_cb = false; + + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_tailq, dynamic.tailq_entry) { + hub->dynamic.flags.waiting_free = 1; + _device_set_actions(hub, DEV_ACTION_RELEASE); + hub->dynamic.state = EXT_HUB_STATE_RELEASED; + call_proc_req_cb = true; + } + TAILQ_FOREACH(hub, &p_ext_hub_driver->dynamic.ext_hubs_pending_tailq, dynamic.tailq_entry) { + hub->dynamic.flags.waiting_free = 1; + hub->dynamic.state = EXT_HUB_STATE_RELEASED; + _device_set_actions(hub, DEV_ACTION_RELEASE); + call_proc_req_cb = true; + } + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } + + return ESP_OK; +} + +esp_err_t ext_hub_status_handle_complete(ext_hub_handle_t ext_hub_hdl) +{ + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + + EXT_HUB_CHECK(ext_hub_dev->dynamic.state == EXT_HUB_STATE_CONFIGURED, ESP_ERR_INVALID_STATE); + + ESP_LOGD(EXT_HUB_TAG, "[%d] Status handle complete, wait status change ...", ext_hub_hdl->constant.dev_addr); + + return device_enable_int_ep(ext_hub_dev); +} + +esp_err_t ext_hub_process(void) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + // Keep processing until all device's with pending events have been handled + while (!TAILQ_EMPTY(&p_ext_hub_driver->dynamic.ext_hubs_pending_tailq)) { + // Move the device back into the idle device list, + ext_hub_dev_t *ext_hub_dev = TAILQ_FIRST(&p_ext_hub_driver->dynamic.ext_hubs_pending_tailq); + TAILQ_REMOVE(&p_ext_hub_driver->dynamic.ext_hubs_pending_tailq, ext_hub_dev, dynamic.tailq_entry); + TAILQ_INSERT_TAIL(&p_ext_hub_driver->dynamic.ext_hubs_tailq, ext_hub_dev, dynamic.tailq_entry); + // Clear the device's flags + uint32_t action_flags = ext_hub_dev->dynamic.action_flags; + ext_hub_dev->dynamic.action_flags = 0; + ext_hub_dev->dynamic.flags.in_pending_list = 0; + + /* --------------------------------------------------------------------- + Exit critical section to handle device action flags in their listed order + --------------------------------------------------------------------- */ + EXT_HUB_EXIT_CRITICAL(); + ESP_LOGD(EXT_HUB_TAG, "[%d] Processing actions 0x%"PRIx32"", ext_hub_dev->constant.dev_addr, action_flags); + + if (action_flags & DEV_ACTION_REQ || + action_flags & DEV_ACTION_EP0_COMPLETE) { + handle_device(ext_hub_dev); + } + if (action_flags & DEV_ACTION_EP1_FLUSH) { + handle_ep1_flush(ext_hub_dev); + } + if (action_flags & DEV_ACTION_EP1_DEQUEUE) { + handle_ep1_dequeue(ext_hub_dev); + } + if (action_flags & DEV_ACTION_EP1_CLEAR) { + handle_ep1_clear(ext_hub_dev); + } + if (action_flags & DEV_ACTION_ERROR) { + handle_error(ext_hub_dev); + } + if (action_flags & DEV_ACTION_GONE) { + handle_gone(ext_hub_dev); + } + if (action_flags & DEV_ACTION_RELEASE) { + device_release(ext_hub_dev); + } + if (action_flags & DEV_ACTION_FREE) { + device_free(ext_hub_dev); + } + EXT_HUB_ENTER_CRITICAL(); + /* --------------------------------------------------------------------- + Re-enter critical sections. All device action flags should have been handled. + --------------------------------------------------------------------- */ + + } + EXT_HUB_EXIT_CRITICAL(); + + return ESP_OK; +} + +// ----------------------------------------------------------------------------- +// --------------------- External Hub - Device related ------------------------- +// ----------------------------------------------------------------------------- + +esp_err_t ext_hub_get_hub_status(ext_hub_handle_t ext_hub_hdl) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = EXT_HUB_STAGE_GET_HUB_STATUS; + bool call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_REQ); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } + + return ESP_OK; +} + +esp_err_t ext_hub_get_status(ext_hub_handle_t ext_hub_hdl) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = EXT_HUB_STAGE_GET_DEVICE_STATUS; + bool call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_REQ); + EXT_HUB_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); + } + + return ESP_OK; +} + +// ----------------------------------------------------------------------------- +// --------------------- External Hub - Port related --------------------------- +// ----------------------------------------------------------------------------- + +esp_err_t ext_hub_port_recycle(ext_hub_handle_t ext_hub_hdl, uint8_t port_num) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + uint8_t port_idx = port_num - 1; + EXT_HUB_CHECK(port_idx < ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + if (p_ext_hub_driver->constant.port_driver) { + ret = p_ext_hub_driver->constant.port_driver->recycle(ext_hub_dev->constant.ports[port_idx]); + } else { + ret = ESP_ERR_NOT_SUPPORTED; + } + return ret; +} + +esp_err_t ext_hub_port_reset(ext_hub_handle_t ext_hub_hdl, uint8_t port_num) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + uint8_t port_idx = port_num - 1; + EXT_HUB_CHECK(port_idx < ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + if (p_ext_hub_driver->constant.port_driver) { + ret = p_ext_hub_driver->constant.port_driver->reset(ext_hub_dev->constant.ports[port_idx]); + } else { + ret = ESP_ERR_NOT_SUPPORTED; + } + return ret; +} + +esp_err_t ext_hub_port_active(ext_hub_handle_t ext_hub_hdl, uint8_t port_num) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + uint8_t port_idx = port_num - 1; + EXT_HUB_CHECK(port_idx < ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + if (p_ext_hub_driver->constant.port_driver) { + ret = p_ext_hub_driver->constant.port_driver->active(ext_hub_dev->constant.ports[port_idx]); + } else { + ret = ESP_ERR_NOT_SUPPORTED; + } + return ret; +} + +esp_err_t ext_hub_port_disable(ext_hub_handle_t ext_hub_hdl, uint8_t port_num) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + uint8_t port_idx = port_num - 1; + EXT_HUB_CHECK(port_idx < ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + if (p_ext_hub_driver->constant.port_driver) { + ret = p_ext_hub_driver->constant.port_driver->disable(ext_hub_dev->constant.ports[port_idx]); + } else { + ret = ESP_ERR_NOT_SUPPORTED; + } + return ret; +} + +esp_err_t ext_hub_port_get_speed(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, usb_speed_t *speed) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + uint8_t port_idx = port_num - 1; + EXT_HUB_CHECK(port_idx < ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + if (p_ext_hub_driver->constant.port_driver) { + ret = p_ext_hub_driver->constant.port_driver->get_speed(ext_hub_dev->constant.ports[port_idx], speed); + } else { + ret = ESP_ERR_NOT_SUPPORTED; + } + return ret; +} + +// ----------------------------------------------------------------------------- +// --------------------------- USB Chapter 11 ---------------------------------- +// ----------------------------------------------------------------------------- + +esp_err_t ext_hub_set_port_feature(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, uint8_t feature) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + usb_transfer_t *transfer = &ext_hub_dev->constant.ctrl_urb->transfer; + + EXT_HUB_CHECK(port_num != 0 && port_num <= ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + + USB_SETUP_PACKET_INIT_SET_PORT_FEATURE((usb_setup_packet_t *)transfer->data_buffer, port_num, feature); + transfer->num_bytes = sizeof(usb_setup_packet_t); + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = EXT_HUB_STAGE_PORT_FEATURE; + EXT_HUB_EXIT_CRITICAL(); + + ret = usbh_dev_submit_ctrl_urb(ext_hub_dev->constant.dev_hdl, ext_hub_dev->constant.ctrl_urb); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Failed to submit ctrl urb, error %#x", ret); + } + return ret; +} + +esp_err_t ext_hub_clear_port_feature(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, uint8_t feature) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + usb_transfer_t *transfer = &ext_hub_dev->constant.ctrl_urb->transfer; + + EXT_HUB_CHECK(port_num != 0 && port_num <= ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + + USB_SETUP_PACKET_INIT_CLEAR_PORT_FEATURE((usb_setup_packet_t *)transfer->data_buffer, port_num, feature); + transfer->num_bytes = sizeof(usb_setup_packet_t); + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = EXT_HUB_STAGE_PORT_FEATURE; + EXT_HUB_EXIT_CRITICAL(); + + ret = usbh_dev_submit_ctrl_urb(ext_hub_dev->constant.dev_hdl, ext_hub_dev->constant.ctrl_urb); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Failed to submit ctrl urb, error %#x", ret); + } + return ret; +} + +esp_err_t ext_hub_get_port_status(ext_hub_handle_t ext_hub_hdl, uint8_t port_num) +{ + EXT_HUB_ENTER_CRITICAL(); + EXT_HUB_CHECK_FROM_CRIT(p_ext_hub_driver != NULL, ESP_ERR_INVALID_STATE); + EXT_HUB_EXIT_CRITICAL(); + + esp_err_t ret; + EXT_HUB_CHECK(ext_hub_hdl != NULL, ESP_ERR_INVALID_ARG); + ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl; + usb_transfer_t *transfer = &ext_hub_dev->constant.ctrl_urb->transfer; + + EXT_HUB_CHECK(port_num != 0 && port_num <= ext_hub_dev->constant.maxchild, ESP_ERR_INVALID_SIZE); + + USB_SETUP_PACKET_INIT_GET_PORT_STATUS((usb_setup_packet_t *)transfer->data_buffer, port_num); + transfer->num_bytes = sizeof(usb_setup_packet_t) + sizeof(usb_port_status_t); + + EXT_HUB_ENTER_CRITICAL(); + ext_hub_dev->dynamic.stage = EXT_HUB_STAGE_PORT_STATUS_REQUEST; + EXT_HUB_EXIT_CRITICAL(); + + ret = usbh_dev_submit_ctrl_urb(ext_hub_dev->constant.dev_hdl, ext_hub_dev->constant.ctrl_urb); + if (ret != ESP_OK) { + ESP_LOGE(EXT_HUB_TAG, "Failed to submit ctrl urb, error %#x", ret); + } + return ret; +} diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index 8187eea9670..9911c624662 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -2437,13 +2437,28 @@ static inline void _buffer_parse_isoc(dma_buffer_block_t *buffer, bool is_in) int desc_status; usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, desc_idx, &rem_len, &desc_status); usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx); - assert(rem_len == 0 || is_in); - assert(desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS || desc_status == USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED); + switch (desc_status) { + case USB_DWC_HAL_XFER_DESC_STS_SUCCESS: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_COMPLETED; + break; + case USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_SKIPPED; + break; + case USB_DWC_HAL_XFER_DESC_STS_PKTERR: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_ERROR; + break; + case USB_DWC_HAL_XFER_DESC_STS_BUFFER_ERR: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_ERROR; + break; + default: + assert(false); + break; + } + assert(rem_len <= transfer->isoc_packet_desc[pkt_idx].num_bytes); // Check for DMA errata // Update ISO packet actual length and status transfer->isoc_packet_desc[pkt_idx].actual_num_bytes = transfer->isoc_packet_desc[pkt_idx].num_bytes - rem_len; total_actual_num_bytes += transfer->isoc_packet_desc[pkt_idx].actual_num_bytes; - transfer->isoc_packet_desc[pkt_idx].status = (desc_status == USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED) ? USB_TRANSFER_STATUS_SKIPPED : USB_TRANSFER_STATUS_COMPLETED; // A descriptor is also allocated for unscheduled frames. We need to skip over them desc_idx += buffer->flags.isoc.interval; if (desc_idx >= XFER_LIST_LEN_INTR) { diff --git a/components/usb/hub.c b/components/usb/hub.c index 4ee318290ea..a11947952f4 100644 --- a/components/usb/hub.c +++ b/components/usb/hub.c @@ -19,6 +19,10 @@ #include "hub.h" #include "usb/usb_helpers.h" +#if ENABLE_USB_HUBS +#include "ext_hub.h" +#endif // ENABLE_USB_HUBS + /* Implementation of the HUB driver that only supports the Root Hub with a single port. Therefore, we currently don't implement the bare minimum to control the root HCD port. @@ -35,13 +39,21 @@ implement the bare minimum to control the root HCD port. #define HUB_ROOT_HCD_PORT_FIFO_BIAS HCD_PORT_FIFO_BIAS_BALANCED #endif -// Hub driver action flags. LISTED IN THE ORDER THEY SHOULD BE HANDLED IN within hub_process(). Some actions are mutually exclusive -#define HUB_DRIVER_FLAG_ACTION_ROOT_EVENT 0x01 -#define HUB_DRIVER_FLAG_ACTION_PORT_REQ 0x02 - #define PORT_REQ_DISABLE 0x01 #define PORT_REQ_RECOVER 0x02 +/** + * @brief Hub driver action flags + */ +typedef enum { + HUB_DRIVER_ACTION_ROOT_EVENT = (1 << 0), + HUB_DRIVER_ACTION_ROOT_REQ = (1 << 1), +#if ENABLE_USB_HUBS + HUB_DRIVER_ACTION_EXT_HUB = (1 << 6), + HUB_DRIVER_ACTION_EXT_PORT = (1 << 7) +#endif // ENABLE_USB_HUBS +} hub_flag_action_t; + /** * @brief Root port states */ @@ -57,7 +69,6 @@ typedef enum { * @brief Hub device tree node * * Object type of a node in the USB device tree that is maintained by the Hub driver - * */ struct dev_tree_node_s { TAILQ_ENTRY(dev_tree_node_s) tailq_entry; /**< Entry for the device tree node object tailq */ @@ -72,11 +83,11 @@ typedef struct { struct { union { struct { - uint32_t actions: 8; - uint32_t reserved24: 24; + hub_flag_action_t actions: 8; /**< Hub actions */ + uint32_t reserved24: 24; /**< Reserved */ }; - uint32_t val; /**< Root port flag value */ - } flags; /**< Root port flags */ + uint32_t val; /**< Hub flag action value */ + } flags; /**< Hub flags */ root_port_state_t root_port_state; /**< Root port state */ unsigned int port_reqs; /**< Root port request flag */ } dynamic; /**< Dynamic members. Require a critical section */ @@ -145,7 +156,7 @@ static bool root_port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port */ static esp_err_t new_dev_tree_node(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num, usb_speed_t speed) { - esp_err_t ret = ESP_FAIL; + esp_err_t ret; unsigned int node_uid = p_hub_driver_obj->single_thread.next_uid; dev_tree_node_t *dev_tree_node = heap_caps_calloc(1, sizeof(dev_tree_node_t), MALLOC_CAP_DEFAULT); @@ -165,6 +176,8 @@ static esp_err_t new_dev_tree_node(usb_device_handle_t parent_dev_hdl, uint8_t p ret = usbh_devs_add(¶ms); if (ret != ESP_OK) { + // USBH devs add could failed due to lack of free hcd channels + // TODO: IDF-10044 Hub should recover after running out of hcd channels goto fail; } @@ -293,12 +306,22 @@ static esp_err_t dev_tree_node_remove_by_parent(usb_device_handle_t parent_dev_h static bool root_port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port_event, void *user_arg, bool in_isr) { HUB_DRIVER_ENTER_CRITICAL_SAFE(); - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_ROOT_EVENT; + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_ACTION_ROOT_EVENT; HUB_DRIVER_EXIT_CRITICAL_SAFE(); assert(in_isr); // Currently, this callback should only ever be called from an ISR context return p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, in_isr, p_hub_driver_obj->constant.proc_req_cb_arg); } +#ifdef ENABLE_USB_HUBS +static bool ext_hub_callback(bool in_isr, void *user_arg) +{ + HUB_DRIVER_ENTER_CRITICAL_SAFE(); + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_ACTION_EXT_HUB; + HUB_DRIVER_EXIT_CRITICAL_SAFE(); + return p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, in_isr, p_hub_driver_obj->constant.proc_req_cb_arg); +} +#endif // ENABLE_USB_HUBS + // ---------------------- Handlers ------------------------- static void root_port_handle_events(hcd_port_handle_t root_port_hdl) { @@ -344,7 +367,7 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl) case ROOT_PORT_STATE_DISABLED: // This occurred after the device has already been disabled // Therefore, there's no device object to clean up, and we can go straight to port recovery p_hub_driver_obj->dynamic.port_reqs |= PORT_REQ_RECOVER; - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT_REQ; + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_ACTION_ROOT_REQ; break; case ROOT_PORT_STATE_ENABLED: // There is an enabled (active) device. We need to indicate to USBH that the device is gone @@ -409,7 +432,7 @@ static esp_err_t root_port_recycle(void) abort(); // Should never occur break; } - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT_REQ; + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_ACTION_ROOT_REQ; HUB_DRIVER_EXIT_CRITICAL(); ESP_ERROR_CHECK(dev_tree_node_remove_by_parent(NULL, 0)); @@ -434,7 +457,20 @@ esp_err_t hub_install(hub_config_t *hub_config, void **client_ret) return ESP_ERR_NO_MEM; } +#if ENABLE_USB_HUBS + // Install External HUB driver + ext_hub_config_t ext_hub_config = { + .proc_req_cb = ext_hub_callback, + .port_driver = NULL, + }; + ret = ext_hub_install(&ext_hub_config); + if (ret != ESP_OK) { + goto err_ext_hub; + } + *client_ret = ext_hub_get_client(); +#else *client_ret = NULL; +#endif // ENABLE_USB_HUBS // Install HCD port hcd_port_config_t port_config = { @@ -474,6 +510,10 @@ esp_err_t hub_install(hub_config_t *hub_config, void **client_ret) assign_err: ESP_ERROR_CHECK(hcd_port_deinit(root_port_hdl)); err: +#if ENABLE_USB_HUBS + ext_hub_uninstall(); +err_ext_hub: +#endif // ENABLE_USB_HUBS heap_caps_free(hub_driver_obj); return ret; } @@ -487,6 +527,10 @@ esp_err_t hub_uninstall(void) p_hub_driver_obj = NULL; HUB_DRIVER_EXIT_CRITICAL(); +#if ENABLE_USB_HUBS + ESP_ERROR_CHECK(ext_hub_uninstall()); +#endif // ENABLE_USB_HUBS + ESP_ERROR_CHECK(hcd_port_deinit(hub_driver_obj->constant.root_port_hdl)); // Free Hub driver resources heap_caps_free(hub_driver_obj); @@ -531,14 +575,19 @@ esp_err_t hub_port_recycle(usb_device_handle_t parent_dev_hdl, uint8_t parent_po HUB_DRIVER_ENTER_CRITICAL(); HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE); HUB_DRIVER_EXIT_CRITICAL(); - - esp_err_t ret = ESP_FAIL; + esp_err_t ret; if (parent_port_num == 0) { ret = root_port_recycle(); } else { - ESP_LOGW(HUB_DRIVER_TAG, "Recycling External Port has not been implemented yet"); - return ESP_ERR_NOT_SUPPORTED; +#if ENABLE_USB_HUBS + ext_hub_handle_t ext_hub_hdl = NULL; + ext_hub_get_handle(parent_dev_hdl, &ext_hub_hdl); + ret = ext_hub_port_recycle(ext_hub_hdl, parent_port_num); +#else + ESP_LOGW(HUB_DRIVER_TAG, "Recycling External Port is not available (External Hub support disabled)"); + ret = ESP_ERR_NOT_SUPPORTED; +#endif // ENABLE_USB_HUBS } return ret; @@ -549,8 +598,7 @@ esp_err_t hub_port_reset(usb_device_handle_t parent_dev_hdl, uint8_t parent_port HUB_DRIVER_ENTER_CRITICAL(); HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE); HUB_DRIVER_EXIT_CRITICAL(); - - esp_err_t ret = ESP_FAIL; + esp_err_t ret; if (parent_port_num == 0) { ret = hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_RESET); @@ -559,13 +607,68 @@ esp_err_t hub_port_reset(usb_device_handle_t parent_dev_hdl, uint8_t parent_port } ret = dev_tree_node_reset_completed(NULL, 0); } else { - ESP_LOGW(HUB_DRIVER_TAG, "Reset External Port has not been implemented yet"); - return ESP_ERR_NOT_SUPPORTED; +#if ENABLE_USB_HUBS + ext_hub_handle_t ext_hub_hdl = NULL; + ext_hub_get_handle(parent_dev_hdl, &ext_hub_hdl); + ret = ext_hub_port_reset(ext_hub_hdl, parent_port_num); +#else + ESP_LOGW(HUB_DRIVER_TAG, "Resetting External Port is not available (External Hub support disabled)"); + ret = ESP_ERR_NOT_SUPPORTED; +#endif // ENABLE_USB_HUBS } + return ret; +} + +esp_err_t hub_port_active(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num) +{ + esp_err_t ret; + if (parent_port_num == 0) { + // Root port no need to be activated + ret = ESP_OK; + } else { +#if ENABLE_USB_HUBS + // External Hub port + ext_hub_handle_t ext_hub_hdl = NULL; + ext_hub_get_handle(parent_dev_hdl, &ext_hub_hdl); + ret = ext_hub_port_active(ext_hub_hdl, parent_port_num); +#else + ESP_LOGW(HUB_DRIVER_TAG, "Activating External Port is not available (External Hub support disabled)"); + ret = ESP_ERR_NOT_SUPPORTED; +#endif // ENABLE_USB_HUBS + } return ret; } +#if ENABLE_USB_HUBS +esp_err_t hub_notify_new_dev(uint8_t dev_addr) +{ + HUB_DRIVER_ENTER_CRITICAL(); + HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE); + HUB_DRIVER_EXIT_CRITICAL(); + + return ext_hub_new_dev(dev_addr); +} + +esp_err_t hub_notify_dev_gone(uint8_t dev_addr) +{ + HUB_DRIVER_ENTER_CRITICAL(); + HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE); + HUB_DRIVER_EXIT_CRITICAL(); + + return ext_hub_dev_gone(dev_addr); +} + +esp_err_t hub_notify_all_free(void) +{ + HUB_DRIVER_ENTER_CRITICAL(); + HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE); + HUB_DRIVER_EXIT_CRITICAL(); + + return ext_hub_all_free(); +} +#endif // ENABLE_USB_HUBS + esp_err_t hub_process(void) { HUB_DRIVER_ENTER_CRITICAL(); @@ -574,10 +677,21 @@ esp_err_t hub_process(void) HUB_DRIVER_EXIT_CRITICAL(); while (action_flags) { - if (action_flags & HUB_DRIVER_FLAG_ACTION_ROOT_EVENT) { +#if ENABLE_USB_HUBS + if (action_flags & HUB_DRIVER_ACTION_EXT_PORT) { + ESP_LOGW(HUB_DRIVER_TAG, "ext_port_process() has not been implemented yet"); + /* + ESP_ERROR_CHECK(ext_port_process()); + */ + } + if (action_flags & HUB_DRIVER_ACTION_EXT_HUB) { + ESP_ERROR_CHECK(ext_hub_process()); + } +#endif // ENABLE_USB_HUBS + if (action_flags & HUB_DRIVER_ACTION_ROOT_EVENT) { root_port_handle_events(p_hub_driver_obj->constant.root_port_hdl); } - if (action_flags & HUB_DRIVER_FLAG_ACTION_PORT_REQ) { + if (action_flags & HUB_DRIVER_ACTION_ROOT_REQ) { root_port_req(p_hub_driver_obj->constant.root_port_hdl); } @@ -586,5 +700,6 @@ esp_err_t hub_process(void) p_hub_driver_obj->dynamic.flags.actions = 0; HUB_DRIVER_EXIT_CRITICAL(); } + return ESP_OK; } diff --git a/components/usb/include/usb/usb_types_ch11.h b/components/usb/include/usb/usb_types_ch11.h index 6d13998cc56..a30e9d3919b 100644 --- a/components/usb/include/usb/usb_types_ch11.h +++ b/components/usb/include/usb/usb_types_ch11.h @@ -66,7 +66,34 @@ typedef enum { } usb_hub_port_feature_t; /** - * @brief Size of a USB Hub Port Status and Hub Change results + * @brief USB Hub characteristics + * + * See USB 2.0 spec Table 11-13, offset 3 + */ +#define USB_W_HUB_CHARS_PORT_PWR_CTRL_ALL (0) /**< All ports power control at once */ +#define USB_W_HUB_CHARS_PORT_PWR_CTRL_INDV (1) /**< Individual port power control */ +#define USB_W_HUB_CHARS_PORT_PWR_CTRL_NO (2) /**< No power switching */ + +#define USB_W_HUB_CHARS_PORT_OVER_CURR_ALL (0) /**< All ports Over-Current reporting */ +#define USB_W_HUB_CHARS_PORT_OVER_CURR_INDV (1) /**< Individual port Over-current reporting */ +#define USB_W_HUB_CHARS_PORT_OVER_CURR_NO (2) /**< No Over-current Protection support */ + +#define USB_W_HUB_CHARS_TTTT_8_BITS (0) /**< TT requires at most 8 FS bit times of inter transaction gap on a full-/low-speed downstream bus */ +#define USB_W_HUB_CHARS_TTTT_16_BITS (1) /**< TT requires at most 16 FS bit times */ +#define USB_W_HUB_CHARS_TTTT_24_BITS (2) /**< TT requires at most 24 FS bit times */ +#define USB_W_HUB_CHARS_TTTT_32_BITS (3) /**< TT requires at most 32 FS bit times */ + +/** + * @brief USB Hub bDeviceProtocol + */ +#define USB_B_DEV_PROTOCOL_HUB_FS (0) /**< Full speed hub */ +#define USB_B_DEV_PROTOCOL_HUB_HS_NO_TT (0) /**< Hi-speed hub without TT */ +#define USB_B_DEV_PROTOCOL_HUB_HS_SINGLE_TT (1) /**< Hi-speed hub with single TT */ +#define USB_B_DEV_PROTOCOL_HUB_HS_MULTI_TT (2) /**< Hi-speed hub with multiple TT */ +#define USB_B_DEV_PROTOCOL_HUB_SS (3) /**< Super speed hub */ + +/** + * @brief USB Hub Port Status and Hub Change results size */ #define USB_PORT_STATUS_SIZE 4 @@ -148,7 +175,17 @@ typedef struct { uint8_t bDescLength; /**< Number of bytes in this descriptor, including this byte */ uint8_t bDescriptorType; /**< Descriptor Type, value: 29H for Hub descriptor */ uint8_t bNbrPorts; /**< Number of downstream facing ports that this Hub supports */ - uint16_t wHubCharacteristics; /**< Logical Power Switching Mode, Compound Device, Over-current Protection Mode, TT Think Time, Port Indicators Supported */ + union { + struct { + uint16_t power_switching: 2; + uint16_t compound: 1; + uint16_t ovr_current_protect: 2; + uint16_t tt_think_time: 2; + uint16_t indicator_support: 1; + uint16_t reserved: 8; + }; + uint16_t val; /**< Hub Characteristics value */ + } wHubCharacteristics; /**< Hub Characteristics */ uint8_t bPwrOn2PwrGood; /**< Time (in 2 ms intervals) from the time the power-on sequence begins on a port until power is good on that port */ uint8_t bHubContrCurrent; /**< Maximum current requirements of the Hub Controller electronics in mA. */ } __attribute__((packed)) usb_hub_descriptor_t; diff --git a/components/usb/include/usb/usb_types_ch9.h b/components/usb/include/usb/usb_types_ch9.h index c09440eb005..500a5dc51c0 100644 --- a/components/usb/include/usb/usb_types_ch9.h +++ b/components/usb/include/usb/usb_types_ch9.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -101,6 +101,21 @@ typedef union { } usb_setup_packet_t; ESP_STATIC_ASSERT(sizeof(usb_setup_packet_t) == USB_SETUP_PACKET_SIZE, "Size of usb_setup_packet_t incorrect"); +/** + * @brief Structure representing a USB device status + * + * See Figures 9-4 Information Returned by a GetStatus() Request to a Device of USB2.0 specification for more details + */ +typedef union { + struct { + uint16_t self_powered: 1; /**< 1 - Device is currently self-powered, 0 - bus powered */ + uint16_t remote_wakeup: 1; /**< 1 - the ability of the device to signal remote wakeup is enabled, 0 - the ability of the device to signal remote wakeup is disabled. */ + uint16_t reserved: 14; /**< reserved */ + } USB_DESC_ATTR; /**< Packed */ + uint16_t val; /**< Device status value */ +} usb_device_status_t; +ESP_STATIC_ASSERT(sizeof(usb_device_status_t) == sizeof(uint16_t), "Size of usb_device_status_t incorrect"); + /** * @brief Bit masks belonging to the bmRequestType field of a setup packet */ @@ -144,6 +159,19 @@ ESP_STATIC_ASSERT(sizeof(usb_setup_packet_t) == USB_SETUP_PACKET_SIZE, "Size of #define USB_W_VALUE_DT_OTHER_SPEED_CONFIG 0x07 #define USB_W_VALUE_DT_INTERFACE_POWER 0x08 +/** + * @brief Initializer for a GET_STATUS request + * + * Sets the address of a connected device + */ +#define USB_SETUP_PACKET_INIT_GET_STATUS(setup_pkt_ptr) ({ \ + (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE; \ + (setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_STATUS; \ + (setup_pkt_ptr)->wValue = 0; \ + (setup_pkt_ptr)->wIndex = 0; \ + (setup_pkt_ptr)->wLength = 2; \ +}) + /** * @brief Initializer for a SET_ADDRESS request * diff --git a/components/usb/private_include/ext_hub.h b/components/usb/private_include/ext_hub.h new file mode 100644 index 00000000000..9fde880fe7e --- /dev/null +++ b/components/usb/private_include/ext_hub.h @@ -0,0 +1,248 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "hcd.h" +#include "usbh.h" +#include "usb/usb_types_stack.h" +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_ch11.h" + +#if CONFIG_USB_HOST_HUB_MULTI_LEVEL +#define ENABLE_MULTIPLE_HUBS 1 +#endif // CONFIG_USB_HOST_HUB_MULTI_LEVEL + +#ifdef __cplusplus +extern "C" { +#endif + +// ----------------------------- Handles --------------------------------------- + +typedef struct ext_hub_s *ext_hub_handle_t; + +// ---------------------------- Callbacks -------------------------------------- + +/** + * @brief Callback used to indicate that the External Hub Driver requires process callback + * For Hub Driver only + */ +typedef bool (*ext_hub_cb_t)(bool in_isr, void *user_arg); + +// ------------------------ External Port API typedefs ------------------------- + +/** + * @brief External Hub Port driver + */ +typedef struct { + esp_err_t (*new)(void *port_cfg, void **port_hdl); + esp_err_t (*reset)(void *port_hdl); + esp_err_t (*recycle)(void *port_hdl); + esp_err_t (*active)(void *port_hdl); + esp_err_t (*disable)(void *port_hdl); + esp_err_t (*gone)(void *port_hdl); + esp_err_t (*free)(void *port_hdl); + esp_err_t (*get_speed)(void *por_hdl, usb_speed_t *speed); + esp_err_t (*get_status)(void *port_hdl); + esp_err_t (*set_status)(void *port_hdl, const usb_port_status_t *status); +} ext_hub_port_driver_t; + +/** + * @brief External Hub Driver configuration + */ +typedef struct { + ext_hub_cb_t proc_req_cb; /**< External Hub process callback */ + void *proc_req_cb_arg; /**< External Hub process callback argument */ + const ext_hub_port_driver_t* port_driver; /**< External Port Driver */ +} ext_hub_config_t; + +// ------------------------------ Driver --------------------------------------- + +/** + * @brief Install External Hub Driver + * + * Entry: + * - should be called within Hub Driver + * + * @param[in] config External Hub driver configuration + * @return esp_err_t + */ +esp_err_t ext_hub_install(const ext_hub_config_t* config); + +/** + * @brief Uninstall External Hub Driver + * + * Entry: + * - should be called within Hub Driver + * + * @return esp_err_t + */ +esp_err_t ext_hub_uninstall(void); + +/** + * @brief External Hub Driver get client pointer + * + * Entry: + * - should be called within Hub Driver + * + * @param[in] config External Hub driver configuration + * @return Unique pointer to identify the External Hub as a USB Host client + */ +void *ext_hub_get_client(void); + +// -------------------------- External Hub API --------------------------------- + +/** + * @brief Get External Hub device handle by USBH device handle + * + * @param[in] dev_hdl USBH device handle + * @param[out] ext_hub_hdl External Hub device handle + * @return esp_err_t + */ +esp_err_t ext_hub_get_handle(usb_device_handle_t dev_hdl, ext_hub_handle_t *ext_hub_hdl); + +/** + * @brief Add new device + * + * After attaching new device: + * - configure it's parameters (requesting hub descriptor) + * + * @param[in] dev_addr Device bus address + * @return esp_err_t + */ +esp_err_t ext_hub_new_dev(uint8_t dev_addr); + +/** + * @brief Device gone + * + * After device were detached: + * - prepare the device to be freed + * + * @param[in] dev_addr Device bus address + * @return esp_err_t + */ +esp_err_t ext_hub_dev_gone(uint8_t dev_addr); + +/** + * @brief Marks all devices to be freed + * + * Entry: + * - should be called within Hub Driver when USB Host library need to be uninstalled + * + * @param[in] dev_addr Device bus address + * @return esp_err_t + */ +esp_err_t ext_hub_all_free(void); + +/** + * @brief The External Hub or Ports statuses change completed + * + * Enables Interrupt IN endpoint to get information about Hub or Ports statuses change + * + * @param[in] ext_hub_hdl External Hub device handle + * @return esp_err_t + */ +esp_err_t ext_hub_status_handle_complete(ext_hub_handle_t ext_hub_hdl); + +/** + * @brief External Hub driver's process function + * + * External Hub driver process function that must be called repeatedly to process the driver's actions and events. + * If blocking, the caller can block on the notification callback of source USB_PROC_REQ_SOURCE_HUB + * to run this function. + */ +esp_err_t ext_hub_process(void); + +// -------------------- External Hub - Port related ---------------------------- + +/** + * @brief Indicate to the External Hub driver that a device's port can be recycled + * + * The device connected to the port has been freed. The Hub driver can now + * recycle the port. + * + * @param[in] ext_hub_hdl External Hub handle + * @param[in] port_num Port number + * @retval ESP_OK: Success + */ +esp_err_t ext_hub_port_recycle(ext_hub_handle_t ext_hub_hdl, uint8_t port_num); + +/** + * @brief Indicate to the External Hub driver that a device's port need a reset + * + * @param[in] ext_hub_hdl External Hub handle + * @param[in] port_num Port number + * @retval ESP_OK: Success + */ +esp_err_t ext_hub_port_reset(ext_hub_handle_t ext_hub_hdl, uint8_t port_num); + +/** + * @brief Indicate to the External Hub driver that a device's port has a device and device has been enumerated + * + * @param[in] ext_hub_hdl External Hub handle + * @param[in] port_num Port number + * @retval ESP_OK: Success + */ +esp_err_t ext_hub_port_active(ext_hub_handle_t ext_hub_hdl, uint8_t port_num); + +/** + * @brief Indicate to the External Hub driver that a device's port should be disabled + * + * @param[in] ext_hub_hdl External Hub handle + * @param[in] port_num Port number + * @retval ESP_OK: Success + */ +esp_err_t ext_hub_port_disable(ext_hub_handle_t ext_hub_hdl, uint8_t port_num); + +/** + * @brief Returns device speed of the device, attached to the port + * + * @param[in] ext_hub_hdl External Hub handle + * @param[in] port_num Port number + * @param[out] speed Devices' speed + * @retval ESP_OK: Success + */ +esp_err_t ext_hub_port_get_speed(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, usb_speed_t *speed); + +// --------------------------- USB Chapter 11 ---------------------------------- + +/** + * @brief Set Port Feature request + * + * @param[in] ext_hub_hdl External Hub device handle + * @param[in] port_num Port number + * @param[in] feature Port Feature to set + * @return esp_err_t + */ +esp_err_t ext_hub_set_port_feature(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, uint8_t feature); + +/** + * @brief Clear Port Feature request + * + * @param[in] ext_hub_hdl External Hub device handle + * @param[in] port_num Port number + * @param[in] feature Port Feature to clear + * @return esp_err_t + */ +esp_err_t ext_hub_clear_port_feature(ext_hub_handle_t ext_hub_hdl, uint8_t port_num, uint8_t feature); + +/** + * @brief Get Port Status request + * + * Sends the request to retrieve port status data. + * Actual port status data could be requested by calling ext_hub_get_port_status() after request completion. + * + * @param[in] ext_hub_hdl External Hub device handle + * @param[in] port_num Port number + * @return esp_err_t + */ +esp_err_t ext_hub_get_port_status(ext_hub_handle_t ext_hub_hdl, uint8_t port_num); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/private_include/hub.h b/components/usb/private_include/hub.h index 5c8361bfb28..067eef790b0 100644 --- a/components/usb/private_include/hub.h +++ b/components/usb/private_include/hub.h @@ -8,10 +8,15 @@ #include #include +#include "sdkconfig.h" #include "esp_err.h" #include "usb_private.h" #include "usbh.h" +#if CONFIG_USB_HOST_HUBS_SUPPORTED +#define ENABLE_USB_HUBS 1 +#endif // CONFIG_USB_HOST_HUBS_SUPPORTED + #ifdef __cplusplus extern "C" { #endif @@ -138,6 +143,50 @@ esp_err_t hub_port_recycle(usb_device_handle_t parent_dev_hdl, uint8_t parent_po */ esp_err_t hub_port_reset(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num); +/** + * @brief Activate the port + * + * @note This function should only be called from the Host Library task + * + * @param[in] parent_dev_hdl Parent device handle (is used to get the External Hub handle) + * @param[in] parent_port_num Parent number (is used to specify the External Port) + * @return + * - ESP_OK: Success + */ +esp_err_t hub_port_active(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num); + +#if ENABLE_USB_HUBS +/** + * @brief Notify Hub driver that new device has been attached + * + * If device is has a HUB class, then it will be added as External Hub to Hub Driver. + * + * @param[in] dev_addr Device bus address + * @return + * - ESP_OK: Success + */ +esp_err_t hub_notify_new_dev(uint8_t dev_addr); + +/** + * @brief Notify Hub driver that device has been removed + * + * If the device was an External Hub, then it will be removed from the Hub Driver. + * + * @param[in] dev_addr Device bus address + * @return + * - ESP_OK: Success + */ +esp_err_t hub_notify_dev_gone(uint8_t dev_addr); + +/** + * @brief Notify Hub driver that all devices should be freed + * + * @return + * - ESP_OK: Success + */ +esp_err_t hub_notify_all_free(void); +#endif // ENABLE_USB_HUBS + /** * @brief Hub driver's processing function * diff --git a/components/usb/usb_host.c b/components/usb/usb_host.c index 1e1ca4c16f2..9bd773007b1 100644 --- a/components/usb/usb_host.c +++ b/components/usb/usb_host.c @@ -227,6 +227,11 @@ static inline bool _is_internal_client(void *client) if (p_host_lib_obj->constant.enum_client && (client == p_host_lib_obj->constant.enum_client)) { return true; } +#if ENABLE_USB_HUBS + if (p_host_lib_obj->constant.hub_client && (client == p_host_lib_obj->constant.hub_client)) { + return true; + } +#endif // ENABLE_USB_HUBS return false; } @@ -311,9 +316,15 @@ static void usbh_event_callback(usbh_event_data_t *event_data, void *arg) .new_dev.address = event_data->new_dev_data.dev_addr, }; send_event_msg_to_clients(&event_msg, true, 0); +#if ENABLE_USB_HUBS + hub_notify_new_dev(event_data->new_dev_data.dev_addr); +#endif // ENABLE_USB_HUBS break; } case USBH_EVENT_DEV_GONE: { +#if ENABLE_USB_HUBS + hub_notify_dev_gone(event_data->new_dev_data.dev_addr); +#endif // ENABLE_USB_HUBS // Prepare event msg, send only to clients that have opened the device usb_host_client_event_msg_t event_msg = { .event = USB_HOST_CLIENT_EVENT_DEV_GONE, @@ -324,9 +335,10 @@ static void usbh_event_callback(usbh_event_data_t *event_data, void *arg) } case USBH_EVENT_DEV_FREE: { // Let the Hub driver know that the device is free and its port can be recycled - ESP_ERROR_CHECK(hub_port_recycle(event_data->dev_free_data.parent_dev_hdl, - event_data->dev_free_data.port_num, - event_data->dev_free_data.dev_uid)); + // Port could be absent, no need to verify + hub_port_recycle(event_data->dev_free_data.parent_dev_hdl, + event_data->dev_free_data.port_num, + event_data->dev_free_data.dev_uid); break; } case USBH_EVENT_ALL_FREE: { @@ -378,6 +390,8 @@ static void enum_event_callback(enum_event_data_t *event_data, void *arg) hub_port_reset(event_data->reset_req.parent_dev_hdl, event_data->reset_req.parent_port_num); break; case ENUM_EVENT_COMPLETED: + // Notify port that device completed enumeration + hub_port_active(event_data->complete.parent_dev_hdl, event_data->complete.parent_port_num); // Propagate a new device event ESP_ERROR_CHECK(usbh_devs_new_dev_event(event_data->complete.dev_hdl)); break; @@ -995,6 +1009,9 @@ esp_err_t usb_host_device_free_all(void) HOST_CHECK_FROM_CRIT(p_host_lib_obj->dynamic.flags.num_clients == 0, ESP_ERR_INVALID_STATE); // All clients must have been deregistered HOST_EXIT_CRITICAL(); esp_err_t ret; +#if ENABLE_USB_HUBS + hub_notify_all_free(); +#endif // ENABLE_USB_HUBS ret = usbh_devs_mark_all_free(); // If ESP_ERR_NOT_FINISHED is returned, caller must wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE to confirm all devices are free return ret; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h index 44f8ca2cc33..248c18a62ca 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -142,7 +142,6 @@ struct wpa_funcs { void (*wpa_config_done)(void); uint8_t *(*owe_build_dhie)(uint16_t group); int (*owe_process_assoc_resp)(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_ie, size_t dh_len); - int (*wpa_sta_set_ap_rsnxe)(const u8 *rsnxe, size_t rsnxe_ie_len); }; struct wpa2_funcs { diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 5d1281f6d8d..8dd2596ed76 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -469,7 +469,6 @@ int esp_supplicant_init(void) wpa_cb->wpa_config_bss = NULL;//wpa_config_bss; wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure; wpa_cb->wpa_config_done = wpa_config_done; - wpa_cb->wpa_sta_set_ap_rsnxe = wpa_sm_set_ap_rsnxe; esp_wifi_register_wpa3_ap_cb(wpa_cb); esp_wifi_register_wpa3_cb(wpa_cb); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index df5448077d3..4e4e1893638 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2434,6 +2434,11 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, if (res < 0) return -1; sm->assoc_wpa_ie_len = res; + + const u8 *rsnxe; + rsnxe = esp_wifi_sta_get_rsnxe((u8*)bssid); + wpa_sm_set_ap_rsnxe(rsnxe, rsnxe ? (rsnxe[1] + 2) : 0); + res = wpa_gen_rsnxe(sm, assoc_rsnxe, assoc_rsnxe_len); if (res < 0) return -1; diff --git a/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png b/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png deleted file mode 100644 index 5b05cc38b4a..00000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png b/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png deleted file mode 100644 index d45410221b5..00000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-isometric.png b/docs/_static/esp32-c3-devkitc-02-v1-isometric.png deleted file mode 100644 index 24636265821..00000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-pinout.png b/docs/_static/esp32-c3-devkitc-02-v1-pinout.png deleted file mode 100644 index 19386275efe..00000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png b/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png deleted file mode 100644 index 1f8b081d5e0..00000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png b/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png deleted file mode 100644 index 29c14e0a0b0..00000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-isometric.png b/docs/_static/esp32-c3-devkitm-1-v1-isometric.png deleted file mode 100644 index 69667b511fd..00000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-pinout.png b/docs/_static/esp32-c3-devkitm-1-v1-pinout.png deleted file mode 100644 index e2022e34dca..00000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-pinout.png and /dev/null differ diff --git a/docs/component_info_ignore_file.txt b/docs/component_info_ignore_file.txt index 21b0fd9c0c6..fd09655d217 100644 --- a/docs/component_info_ignore_file.txt +++ b/docs/component_info_ignore_file.txt @@ -7,6 +7,7 @@ components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h +components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h # ESSL headers do not belong to any IDF component, in a user project it will come from a managed component components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h diff --git a/docs/conf_common.py b/docs/conf_common.py index 053c47d3b74..fc29c450289 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -117,7 +117,8 @@ 'api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst', 'api-reference/peripherals/usb_host/usb_host_notes_index.rst', 'api-reference/peripherals/usb_host/usb_host_notes_usbh.rst', - 'api-reference/peripherals/usb_host/usb_host_notes_enum.rst'] + 'api-reference/peripherals/usb_host/usb_host_notes_enum.rst', + 'api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst'] I80_LCD_DOCS = ['api-reference/peripherals/lcd/i80_lcd.rst'] RGB_LCD_DOCS = ['api-reference/peripherals/lcd/rgb_lcd.rst'] diff --git a/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index dc5ef2a728a..10d49479d1f 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -86,6 +86,7 @@ api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst api-reference/peripherals/usb_host/usb_host_notes_design.rst api-reference/peripherals/usb_host/usb_host_notes_usbh.rst api-reference/peripherals/usb_host/usb_host_notes_enum.rst +api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst api-reference/peripherals/usb_device.rst api-reference/peripherals/sdspi_host.rst api-reference/peripherals/spi_slave.rst @@ -96,7 +97,6 @@ api-reference/peripherals/lcd.rst api-reference/peripherals/ana_cmpr.rst api-reference/peripherals/temp_sensor.rst api-reference/peripherals/spi_features.rst -api-reference/peripherals/clk_tree.rst api-reference/peripherals/spi_flash/spi_flash_concurrency.rst api-reference/peripherals/spi_flash/spi_flash_override_driver.rst api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 828989eb391..06a53790b76 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -18,6 +18,7 @@ api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst api-reference/peripherals/usb_host/usb_host_notes_design.rst api-reference/peripherals/usb_host/usb_host_notes_usbh.rst api-reference/peripherals/usb_host/usb_host_notes_enum.rst +api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst api-reference/peripherals/usb_device.rst api-reference/peripherals/touch_element.rst api-reference/peripherals/spi_flash/xip_from_psram.inc diff --git a/docs/doxygen/Doxyfile_esp32p4 b/docs/doxygen/Doxyfile_esp32p4 index 1c9f7aa9dbe..58fd99650ef 100644 --- a/docs/doxygen/Doxyfile_esp32p4 +++ b/docs/doxygen/Doxyfile_esp32p4 @@ -1,6 +1,7 @@ INPUT += \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_uart.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_spi.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/ulp_lp_core.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_i2c.h \ @@ -8,6 +9,7 @@ INPUT += \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h \ $(PROJECT_PATH)/components/ulp/ulp_common/include/ulp_common.h \ $(PROJECT_PATH)/components/usb/include/usb/usb_helpers.h \ $(PROJECT_PATH)/components/usb/include/usb/usb_host.h \ diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 8f022e98adb..e708d26ac82 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -1,6 +1,8 @@ Copyrights and Licenses *********************** +:link_to_translation:`zh_CN:[中文]` + Software Copyrights =================== @@ -21,62 +23,62 @@ These third party libraries can be included into the application (firmware) prod * :component:`Xtensa header files ` are Copyright (C) 2013 Tensilica Inc and are licensed under the MIT License as reproduced in the individual header files. -* Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2017 Amazon.com, Inc. or its affiliates are licensed under the MIT License, as described in :component_file:`license.txt `. +* Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2017 Amazon.com, Inc. or its affiliates, and are licensed under the MIT License, as described in :component_file:`license.txt `. * Original parts of LWIP_ (components/lwip) are Copyright (C) 2001, 2002 Swedish Institute of Computer Science and are licensed under the BSD License as described in :component_file:`COPYING file `. -* `wpa_supplicant`_ Copyright (c) 2003-2022 Jouni Malinen and contributors and licensed under the BSD license. +* `wpa_supplicant`_, Copyright (C) 2003-2022 Jouni Malinen and contributors and licensed under the BSD License. -* :component_file:`Fast PBKDF2 ` Copyright (c) 2015 Joseph Birr-Pixton and licensed under CC0 Public Domain Dedication license. +* :component_file:`Fast PBKDF2 `, Copyright (C) 2015 Joseph Birr-Pixton and licensed under CC0 Public Domain Dedication License. -* `FreeBSD net80211`_ Copyright (c) 2004-2008 Sam Leffler, Errno Consulting and licensed under the BSD license. +* `FreeBSD net80211`_, Copyright (C) 2004-2008 Sam Leffler, Errno Consulting and licensed under the BSD License. -* `argtable3`_ argument parsing library Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann and licensed under 3-clause BSD license. argtable3 also includes the following software components. For details, please see argtable3 :component_file:`LICENSE file `. +* `argtable3`_ argument parsing library, Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann and licensed under 3-clause BSD license. argtable3 also includes the following software components. For details, please see argtable3 :component_file:`LICENSE file `. - * C Hash Table library, Copyright (c) 2002, Christopher Clark and licensed under 3-clause BSD license. - * The Better String library, Copyright (c) 2014, Paul Hsieh and licensed under 3-clause BSD license. + * C Hash Table library, Copyright (C) 2002 Christopher Clark and licensed under 3-clause BSD License. + * The Better String library, Copyright (C) 2014 Paul Hsieh and licensed under 3-clause BSD License. * TCL library, Copyright the Regents of the University of California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState Corporation and other parties, and licensed under TCL/TK License. -* `linenoise`_ line editing library Copyright (c) 2010-2014 Salvatore Sanfilippo, Copyright (c) 2010-2013 Pieter Noordhuis, licensed under 2-clause BSD license. +* `linenoise`_ line editing library, Copyright (C) 2010-2014 Salvatore Sanfilippo, Copyright (C) 2010-2013 Pieter Noordhuis, licensed under 2-clause BSD License. * `FatFS`_ library, Copyright (C) 2017 ChaN, is licensed under :component_file:`a BSD-style license `. -* `cJSON`_ library, Copyright (c) 2009-2017 Dave Gamble and cJSON contributors, is licensed under MIT license as described in :component_file:`LICENSE file `. +* `cJSON`_ library, Copyright (C) 2009-2017 Dave Gamble and cJSON contributors, is licensed under MIT License as described in :component_file:`LICENSE file `. -* `micro-ecc`_ library, Copyright (c) 2014 Kenneth MacKay, is licensed under 2-clause BSD license. +* `micro-ecc`_ library, Copyright (C) 2014 Kenneth MacKay, is licensed under 2-clause BSD License. * `Mbed TLS`_ library, Copyright (C) 2006-2018 ARM Limited, is licensed under Apache License 2.0 as described in :component_file:`LICENSE file `. -* `SPIFFS`_ library, Copyright (c) 2013-2017 Peter Andersson, is licensed under MIT license as described in :component_file:`LICENSE file `. +* `SPIFFS`_ library, Copyright (C) 2013-2017 Peter Andersson, is licensed under MIT License as described in :component_file:`LICENSE file `. -* :component_file:`SD/MMC driver ` is derived from `OpenBSD SD/MMC driver`_, Copyright (c) 2006 Uwe Stuehler, and is licensed under BSD license. +* :component_file:`SD/MMC driver ` is derived from `OpenBSD SD/MMC driver`_, Copyright (C) 2006 Uwe Stuehler, and is licensed under BSD License. -* :component:`ESP-MQTT ` MQTT Package (contiki-mqtt) - Copyright (c) 2014, Stephen Robinson, MQTT-ESP - Tuan PM is licensed under Apache License 2.0 as described in :component_file:`LICENSE file `. +* :component:`ESP-MQTT ` Package (contiki-mqtt), Copyright (C) 2014 Stephen Robinson, MQTT-ESP - Tuan PM is licensed under Apache License 2.0 as described in :component_file:`LICENSE file `. -* :component:`BLE Mesh ` is adapted from Zephyr Project, Copyright (c) 2017-2018 Intel Corporation and licensed under Apache License 2.0. +* :component:`BLE Mesh ` is adapted from Zephyr Project, Copyright (C) 2017-2018 Intel Corporation and licensed under Apache License 2.0. -* `mynewt-nimble`_ Apache Mynewt NimBLE, Copyright 2015-2018, The Apache Software Foundation, is licensed under Apache License 2.0 as described in :component_file:`LICENSE file `. +* `mynewt-nimble`_, Copyright (C) 2015-2018 The Apache Software Foundation, is licensed under Apache License 2.0 as described in :component_file:`LICENSE file `. -* `TLSF allocator `_ Two Level Segregated Fit memory allocator, Copyright (c) 2006-2016, Matthew Conte, and licensed under the BSD 3-clause license. +* `TLSF allocator `_, Copyright (C) 2006-2016 Matthew Conte, and licensed under the BSD 3-clause license. -* :component:`openthread`, Copyright (c) The OpenThread Authors, is licensed under BSD License as described in :component_file:`LICENSE file `. +* :component:`openthread`, Copyright (C) The OpenThread Authors, is licensed under BSD License as described in :component_file:`LICENSE file `. -* :component_file:`UBSAN runtime ` — Copyright (c) 2016, Linaro Limited and Jiří Zárevúcky, licensed under the BSD 2-clause license. +* :component_file:`UBSAN runtime `, Copyright (C) 2016 Linaro Limited and Jiří Zárevúcky, licensed under the BSD 2-clause license. -* :component:`HTTP Parser ` Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev. Additional changes are licensed under the same terms as NGINX and Joyent, Inc. and other Node contributors. For details please check :component_file:`LICENSE file `. +* :component:`HTTP Parser ` is based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev. Additional changes are licensed under the same terms as NGINX and Joyent, Inc. and other Node contributors. For details please check :component_file:`LICENSE file `. -* `SEGGER SystemView`_ target-side library, Copyright (c) 1995-2021 SEGGER Microcontroller GmbH, is licensed under BSD 1-clause license. +* `SEGGER SystemView`_ target-side library, Copyright (C) 1995-2021 SEGGER Microcontroller GmbH, is licensed under BSD 1-clause license. -* `protobuf-c`_ Protocol Buffers implementation in C, Copyright (c) 2008-2022, Dave Benson and the protobuf-c authors. For details please check :component_file:`LICENSE file `. +* `protobuf-c`_ is Protocol Buffers implementation in C, Copyright (C) 2008-2022 Dave Benson and the protobuf-c authors. For details please check :component_file:`LICENSE file `. -* `CMock`_ Mock/stub generator for C, Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams, is licensed under MIT license as described in :component_file:`LICENSE file `. +* `CMock`_ mock/stub generator for C, Copyright (C) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams, is licensed under MIT License as described in :component_file:`LICENSE file `. -* `Unity`_ Simple Unit Testing library, Copyright (c) 2007-23 Mike Karlesky, Mark VanderVoord, Greg Williams, is licensed under MIT license as described in :component_file:`LICENSE file `. +* `Unity`_ Simple Unit Testing library, Copyright (C) 2007-23 Mike Karlesky, Mark VanderVoord, Greg Williams, is licensed under MIT License as described in :component_file:`LICENSE file `. Documentation ------------- -* HTML version of the `ESP-IDF Programming Guide`_ uses the Sphinx theme `sphinx_idf_theme`_, which is Copyright (c) 2013-2020 Dave Snider, Read the Docs, Inc. & contributors, and Espressif Systems (Shanghai) CO., LTD. It is based on `sphinx_rtd_theme`_. Both are licensed under MIT license. +* HTML version of the `ESP-IDF Programming Guide`_ uses the Sphinx theme `sphinx_idf_theme`_, which is Copyright (C) 2013-2020 Dave Snider, Read the Docs, Inc. & contributors, and Espressif Systems (Shanghai) CO., LTD. It is based on `sphinx_rtd_theme`_. Both are licensed under MIT License. ROM Source Code Copyrights ========================== @@ -85,20 +87,20 @@ Espressif SoCs mask ROM hardware includes binaries compiled from portions of the * :component:`Newlib `, licensed under the BSD License and is Copyright of various parties, as described in :component_file:`COPYING.NEWLIB `. -* Xtensa libhal, Copyright (c) Tensilica Inc and licensed under the MIT license (see below). +* Xtensa libhal, Copyright (C) Tensilica Inc and licensed under the MIT License (see below). -* TinyBasic_ Plus, Copyright Mike Field & Scott Lawrence and licensed under the MIT license (see below). +* TinyBasic_ Plus, Copyright (C) Mike Field & Scott Lawrence and licensed under the MIT License (see below). * miniz_, by Rich Geldreich - placed into the public domain. -* TJpgDec_ Copyright (C) 2011, ChaN, all right reserved. See below for license. +* TJpgDec_, Copyright (C) 2011 ChaN, all right reserved. See below for license. * Parts of Zephyr RTOS USB stack: - * `DesignWare USB device driver`_ Copyright (c) 2016 Intel Corporation and licensed under Apache 2.0 license. - * `Generic USB device driver`_ Copyright (c) 2006 Bertrik Sikken (bertrik@sikken.nl), 2016 Intel Corporation and licensed under BSD 3-clause license. - * `USB descriptors functionality`_ Copyright (c) 2017 PHYTEC Messtechnik GmbH, 2017-2018 Intel Corporation and licensed under Apache 2.0 license. - * `USB DFU class driver`_ Copyright (c) 2015-2016 Intel Corporation, 2017 PHYTEC Messtechnik GmbH and licensed under BSD 3-clause license. - * `USB CDC ACM class driver`_ Copyright (c) 2015-2016 Intel Corporation and licensed under Apache 2.0 license. + * `DesignWare USB device driver`_, Copyright (C) 2016 Intel Corporation and licensed under Apache License 2.0. + * `Generic USB device driver`_, Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl), 2016 Intel Corporation and licensed under BSD 3-clause license. + * `USB descriptors functionality`_, Copyright (C) 2017 PHYTEC Messtechnik GmbH, 2017-2018 Intel Corporation and licensed under Apache License 2.0. + * `USB DFU class driver`_, Copyright (C) 2015-2016 Intel Corporation, 2017 PHYTEC Messtechnik GmbH and licensed under BSD 3-clause license. + * `USB CDC ACM class driver`_, Copyright (C) 2015-2016 Intel Corporation and licensed under Apache License 2.0. .. only:: CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB @@ -107,31 +109,18 @@ Espressif SoCs mask ROM hardware includes binaries compiled from portions of the Xtensa libhal MIT License ========================= -Copyright (c) 2003, 2006, 2010 Tensilica Inc. +Copyright (C) 2003, 2006, 2010 Tensilica Inc. -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. TinyBasic Plus MIT License ========================== -Copyright (c) 2012-2013 +Copyright (C) 2012-2013 Mike Field & Scott Lawrence. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -142,12 +131,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI TJpgDec License =============== -TJpgDec - Tiny JPEG Decompressor R0.01 (C) ChaN, 2011 -The TJpgDec is a generic JPEG decompressor module for tiny embedded systems. -This is a free software that opened for education, research and commercial -developments under license policy of following terms. +TJpgDec - Tiny JPEG Decompressor R0.01 (C) 2011 ChaN, is a generic JPEG decompressor module for tiny embedded systems.This is a free software that opened for education, research and commercial developments under license policy of following terms: -Copyright (C) 2011, ChaN, all right reserved. +Copyright (C) 2011 ChaN, all right reserved. * The TJpgDec module is a free software and there is NO WARRANTY. * No restriction on use. You can use, modify and redistribute it for personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index e0f779f78a5..34cb4de03ae 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -26,7 +26,7 @@ Hardware .. only:: esp32 or esp32s2 or esp32s3 - Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on bootup, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. + Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on boot-up, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. .. only:: esp32p4 @@ -55,8 +55,7 @@ ESP-IDF fully supports the use of external RAM in applications. Once the externa * :ref:`external_ram_config_malloc` (default) * :ref:`external_ram_config_bss` :esp32: * :ref:`external_ram_config_noinit` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_instructions` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_rodata` + :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_xip` .. _external_ram_config_memory_map: @@ -139,8 +138,6 @@ Remaining external RAM can also be added to the capability heap allocator using .. only:: esp32s2 or esp32s3 - .. _external_ram_config_instructions: - Move Instructions in Flash to PSRAM ----------------------------------- @@ -152,8 +149,6 @@ Remaining external RAM can also be added to the capability heap allocator using - The corresponding virtual memory range of those instructions will also be re-mapped to PSRAM. - .. _external_ram_config_rodata: - Move Read-Only Data in Flash to PSRAM --------------------------------------- @@ -165,6 +160,7 @@ Remaining external RAM can also be added to the capability heap allocator using - The corresponding virtual memory range of those rodata will also be re-mapped to PSRAM. + .. _external_ram_config_xip: Execute In Place (XiP) from PSRAM ------------------------------------ @@ -179,12 +175,14 @@ Remaining external RAM can also be added to the capability heap allocator using .. only:: esp32p4 + .. _external_ram_config_xip: + Execute In Place (XiP) from PSRAM ------------------------------------ - The :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` option enables the executable in place (XiP) from PSRAM feature. With this option sections that are normally placed in flash ,``.text`` (for instructions) and ``.rodata`` (for read only data), will be loaded in PSRAM. + The :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` option enables the executable in place (XiP) from PSRAM feature. With this option sections that are normally placed in flash, ``.text`` (for instructions) and ``.rodata`` (for read only data), will be loaded in PSRAM. - With this option enabled, the cache will not be disabled during an SPI1 flash operation, so code that requires executing during an SPI1 Flash operation does not have to be placed in internal RAM. Because P4 Flash and PSRAM are using two separate SPI buses, moving Flash content to PSRAM will actually increase the load of the PSRAM MSPI bus, so the access speed is relatively slower. The exact impact on performance will be very dependent on your apps usage of PSRAM, and we suggest doing performance profiling to determine if enabling this option will significantly impact your app's performance. + With this option enabled, the cache will not be disabled during an SPI1 flash operation, so code that requires executing during an SPI1 flash operation does not have to be placed in internal RAM. Because P4 flash and PSRAM are using two separate SPI buses, moving flash content to PSRAM will actually increase the load of the PSRAM MSPI bus, so the access speed is relatively slower. The exact impact on performance will be very dependent on your apps usage of PSRAM, and we suggest doing performance profiling to determine if enabling this option will significantly impact your app's performance. Restrictions diff --git a/docs/en/api-guides/performance/size.rst b/docs/en/api-guides/performance/size.rst index b38a2b7d1e0..f88f8a38bc9 100644 --- a/docs/en/api-guides/performance/size.rst +++ b/docs/en/api-guides/performance/size.rst @@ -3,8 +3,6 @@ Minimizing Binary Size :link_to_translation:`zh_CN:[中文]` -{IDF_TARGET_REDUCED_BY_IRAM: default="DRAM", esp32="IRAM and/or DRAM (depending on sizes)"} - The ESP-IDF build system compiles all source files in the project and ESP-IDF, but only functions and variables that are actually referenced by the program are linked into the final binary. In some cases, it is necessary to reduce the total size of the firmware binary, e.g., in order to fit it into the available flash partition size. The first step to reducing the total firmware binary size is measuring what is causing the size to increase. @@ -14,312 +12,12 @@ The first step to reducing the total firmware binary size is measuring what is c Measuring Static Sizes ---------------------- -To optimize both the firmware binary size and the memory usage, it is necessary to measure statically-allocated RAM (``data``, ``bss``), code (``text``), and read-only data (``rodata``) in your project. - -Using the :ref:`idf.py` sub-commands ``size``, ``size-components``, and ``size-files`` provides a summary of memory used by the project: - -.. note:: - - It is possible to add ``-DOUTPUT_FORMAT=csv`` or ``-DOUTPUT_FORMAT=json`` to get the output in CSV or JSON format. - -Size Summary ``idf.py size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. only:: esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used static DRAM: 10608 bytes ( 170128 remain, 5.9% used) - .data size: 8464 bytes - .bss size: 2144 bytes - Used static IRAM: 48834 bytes ( 82238 remain, 37.3% used) - .text size: 47807 bytes - .vectors size: 1027 bytes - Used Flash size : 117391 bytes - .text: 80103 bytes - .rodata: 37032 bytes - Total image size: 174689 bytes (.bin may be padded larger) - - -.. only:: not esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used stat D/IRAM: 53743 bytes ( 122385 remain, 30.5% used) - .data size: 6504 bytes - .bss size: 1984 bytes - .text size: 44228 bytes - .vectors size: 1027 bytes - Used Flash size : 118879 bytes - .text: 83467 bytes - .rodata: 35156 bytes - Total image size: 170638 bytes (.bin may be padded larger) - -This output breaks down the size of all static memory regions in the firmware binary: - -.. only:: esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used static DRAM: 10608 bytes ( 170128 remain, 5.9% used) - .data size: 8464 bytes - .bss size: 2144 bytes - Used static IRAM: 48834 bytes ( 82238 remain, 37.3% used) - .text size: 47807 bytes - .vectors size: 1027 bytes - Used Flash size : 117391 bytes - .text: 80103 bytes - .rodata: 37032 bytes - Total image size: 174689 bytes (.bin may be padded larger) - - - ``Used static DRAM``: Total amount of DRAM allocated at compile time. ``remain`` indicates the amount of DRAM left to be used as heap memory at runtime. Note that due to meta data overhead, implementation constraints, and startup heap allocations, the actual size of the DRAM heap is smaller. - - - ``.data size``: Amount of DRAM allocated at compile time for the ``.data`` (i.e., all statically allocated variables that are initialized to non-zero values). ``.data`` also consumes space in the binary image to store the non-zero initialization values. - - ``.bss size``: Amount of DRAM allocated at compile time for ``.bss`` (i.e., all statically allocated variables that are initialized to zero). ``.bss`` does not consume extra space in flash. - - - ``Used static IRAM``: Total amount of IRAM allocated at compile time. ``remain`` indicates the amount of IRAM left to be used as heap memory at runtime. Note that due to meta data overhead, implementation constraints, and startup heap allocations, the actual size of the IRAM heap is smaller. - - - ``.text size``: Amount of IRAM used for ``.text`` (i.e., all code that is executed from :ref:`IRAM `). ``.text`` also consumes space in the binary image as the code is initially stored there and is then copied over to IRAM on startup. - - - ``Used Flash size``: Total amount of flash used (excluding usage by DRAM and IRAM) - - - ``.text``: Amount of flash used for ``.text`` (i.e., all code that is executed via the flash cache, see :ref:`IROM `). - - ``.rodata``: Amount of flash used for ``.rodata`` (i.e., read-only data that is loaded via the flash cache, see :ref:`DROM `). - - - ``Total image size`` is the estimated total size of the binary file. - -.. only:: not esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used stat D/IRAM: 53743 bytes ( 122385 remain, 30.5% used) - .data size: 6504 bytes - .bss size: 1984 bytes - .text size: 44228 bytes - .vectors size: 1027 bytes - Used Flash size : 118879 bytes - .text: 83467 bytes - .rodata: 35156 bytes - Total image size: 170638 bytes (.bin may be padded larger) - - - ``Used stat D/IRAM``: Total amount of D/IRAM used at compile time. ``remain`` indicates the amount of D/IRAM left to be used as heap memory at runtime. Note that due to meta data overhead, implementation constraints, and startup heap allocations, the actual size of the DRAM heap is smaller. - - - ``.data size``: Amount of D/IRAM allocated at compile time for the ``.data`` (i.e., all statically allocated variables that are initialized to non-zero values). ``.data`` also consumes space in the binary image to store the non-zero initialization values. - - ``.bss size``: Amount of D/IRAM allocated at compile time for ``.bss`` (i.e., all statically allocated variables that are initialized to zero). ``.bss`` does not consume extra space in flash. - - ``.text size``: Amount of D/IRAM used for ``.text`` (i.e., all code that is executed from internal RAM). ``.text`` also consumes space in the binary image as the code is initially stored there and is then copied over to D/IRAM on startup. - - - ``Used Flash size``: Total amount of flash used (excluding usage by D/IRAM) - - - ``.text``: Amount of flash used for ``.text`` (i.e., all code that is executed via the flash cache, see :ref:`IROM `). - - ``.rodata``: Amount of flash used for ``.rodata`` (i.e., read-only data that is loaded via the flash cache, see :ref:`DROM `). - - - ``Total image size`` is the estimated total size of the binary file. - - -Component Usage Summary ``idf.py size-components`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The summary output provided by ``idf.py size`` does not give enough details to find the main contributor to excessive binary size. To analyze in detail, use ``idf.py size-components``. - -.. code-block:: bash - - $ idf.py size-components - [...] - Total sizes: - DRAM .data size: 14956 bytes - DRAM .bss size: 15808 bytes - Used static DRAM: 30764 bytes ( 149972 available, 17.0% used) - Used static IRAM: 83918 bytes ( 47154 available, 64.0% used) - Flash code: 559943 bytes - Flash rodata: 176736 bytes - Total image size:~ 835553 bytes (.bin may be padded larger) - Per-archive contributions to ELF file: - Archive File DRAM .data & .bss & other IRAM D/IRAM Flash code & rodata Total - libnet80211.a 1267 6044 0 5490 0 107445 18484 138730 - liblwip.a 21 3838 0 0 0 97465 16116 117440 - libmbedtls.a 60 524 0 0 0 27655 69907 98146 - libmbedcrypto.a 64 81 0 30 0 76645 11661 88481 - libpp.a 2427 1292 0 20851 0 37208 4708 66486 - libc.a 4 0 0 0 0 57056 6455 63515 - libphy.a 1439 715 0 7798 0 33074 0 43026 - libwpa_supplicant.a 12 848 0 0 0 35505 1446 37811 - libfreertos.a 3104 740 0 15711 0 367 4228 24150 - libnvs_flash.a 0 24 0 0 0 14347 2924 17295 - libspi_flash.a 1562 294 0 8851 0 1840 1913 14460 - libesp_system.a 245 206 0 3078 0 5990 3817 13336 - libesp-tls.a 0 4 0 0 0 5637 3524 9165 - [... removed some lines here ...] - libesp_rom.a 0 0 0 112 0 0 0 112 - libcxx.a 0 0 0 0 0 47 0 47 - (exe) 0 0 0 3 0 3 12 18 - libesp_pm.a 0 0 0 0 0 8 0 8 - libesp_eth.a 0 0 0 0 0 0 0 0 - libmesh.a 0 0 0 0 0 0 0 0 - -The first lines of the output from ``idf.py size-components`` are the same as that from ``idf.py size``. After this, a table is printed as ``Per-archive contributions to ELF file``. This means how much each static library archive has contributed to the final binary size. - -Generally, one static library archive is built per component, although some are binary libraries included by a particular component, for example, ``libnet80211.a`` is included by ``esp_wifi`` component. There are also toolchain libraries such as ``libc.a`` and ``libgcc.a`` listed here, these provide Standard C/C++ Library and toolchain built-in functionality. - -If your project is simple and only has a ``main`` component, then all of the project's code will be shown under ``libmain.a``. If your project includes its own components (see :doc:`/api-guides/build-system`), then they will each be shown on a separate line. - -The table is sorted in descending order of the total contribution of the static archive to the binary size. - -The columns are as follows: - -.. list:: - - - ``DRAM .data & .bss & other`` - ``.data`` and ``.bss`` are the same as for the totals shown above. Both are static variables and reduce the total available RAM at runtime, but ``.bss`` does not contribute to the binary file size. ``other`` is a column for any custom section types that also contribute to RAM size. Usually, the value is 0. - :esp32: - ``IRAM`` - is the same as for the totals shown above. It refers to code linked to execute from IRAM, which uses space in the binary file and also reduces IRAM that can be dynamically allocated at runtime using ``HEAP_CAP_32BIT``. - :esp32: - ``D/IRAM`` - shows IRAM space which, due to occupying D/IRAM space, is also reducing available DRAM available as heap at runtime. - :not esp32: - ``IRAM`` - is the same as for the totals shown above. It refers to code linked to execute from IRAM, which uses space in the binary file and also reduces DRAM available as heap at runtime. - - ``Flash code & rodata`` - these are the same as the totals above, IROM and DROM space accessed from the flash cache that contribute to the binary size. - -Source File Usage Summary ``idf.py size-files`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For even more details, run ``idf.py size-files`` to get a summary of the contribution each object file has made to the final binary size. Each object file corresponds to a single source file. - -.. code-block:: bash - - $ idf.py size-files - [...] - Total sizes: - DRAM .data size: 14956 bytes - DRAM .bss size: 15808 bytes - Used static DRAM: 30764 bytes ( 149972 available, 17.0% used) - Used static IRAM: 83918 bytes ( 47154 available, 64.0% used) - Flash code: 559943 bytes - Flash rodata: 176736 bytes - Total image size:~ 835553 bytes (.bin may be padded larger) - Per-file contributions to ELF file: - Object File DRAM .data & .bss & other IRAM D/IRAM Flash code & rodata Total - x509_crt_bundle.S.o 0 0 0 0 0 0 64212 64212 - wl_cnx.o 2 3183 0 221 0 13119 3286 19811 - phy_chip_v7.o 721 614 0 1642 0 16820 0 19797 - ieee80211_ioctl.o 740 96 0 437 0 15325 2627 19225 - pp.o 1142 45 0 8871 0 5030 537 15625 - ieee80211_output.o 2 20 0 2118 0 11617 914 14671 - ieee80211_sta.o 1 41 0 1498 0 10858 2218 14616 - lib_a-vfprintf.o 0 0 0 0 0 13829 752 14581 - lib_a-svfprintf.o 0 0 0 0 0 13251 752 14003 - ssl_tls.c.o 60 0 0 0 0 12769 463 13292 - sockets.c.o 0 648 0 0 0 11096 1030 12774 - nd6.c.o 8 932 0 0 0 11515 314 12769 - phy_chip_v7_cal.o 477 53 0 3499 0 8561 0 12590 - pm.o 32 364 0 2673 0 7788 782 11639 - ieee80211_scan.o 18 288 0 0 0 8889 1921 11116 - lib_a-svfiprintf.o 0 0 0 0 0 9654 1206 10860 - lib_a-vfiprintf.o 0 0 0 0 0 10069 734 10803 - ieee80211_ht.o 0 4 0 1186 0 8628 898 10716 - phy_chip_v7_ana.o 241 48 0 2657 0 7677 0 10623 - bignum.c.o 0 4 0 0 0 9652 752 10408 - tcp_in.c.o 0 52 0 0 0 8750 1282 10084 - trc.o 664 88 0 1726 0 6245 1108 9831 - tasks.c.o 8 704 0 7594 0 0 1475 9781 - ecp_curves.c.o 28 0 0 0 0 7384 2325 9737 - ecp.c.o 0 64 0 0 0 8864 286 9214 - ieee80211_hostap.o 1 41 0 0 0 8578 585 9205 - wdev.o 121 125 0 4499 0 3684 580 9009 - tcp_out.c.o 0 0 0 0 0 5686 2161 7847 - tcp.c.o 2 26 0 0 0 6161 1617 7806 - ieee80211_input.o 0 0 0 0 0 6797 973 7770 - wpa.c.o 0 656 0 0 0 6828 55 7539 - [... additional lines removed ...] - -After the summary of total sizes, a table of ``Per-file contributions to ELF file`` is printed. - -The columns are the same as shown above for ``idy.py size-components``, but this time the granularity is the contribution of each individual object file to the binary size. - -For example, we can see that the file ``x509_crt_bundle.S.o`` contributed 64,212 bytes to the total firmware size, all as ``.rodata`` in flash. Therefore we can guess that this application is using the :doc:`/api-reference/protocols/esp_crt_bundle` feature and not using this feature would save at last this many bytes from the firmware size. - -Some of the object files are linked from binary libraries and therefore you will not find a corresponding source file. To locate which component a source file belongs to, it is generally possible to search in the ESP-IDF source tree or look in the :ref:`linker-map-file` for the full path. - -Comparing Two Binaries -^^^^^^^^^^^^^^^^^^^^^^ - -If making some changes that affect binary size, it is possible to use an ESP-IDF tool to break down the exact differences in size. - -This operation is not part of ``idf.py``, it is necessary to run the `esp_idf_size `_ Python tool directly. - -To do so, first, locate the linker map file with the name ``PROJECTNAME.map`` in the build directory. The ``esp_idf_size`` tool performs its analysis based on the output of the linker map file. - -To compare with another binary, you also need its corresponding ``.map`` file saved from the build directory. - -For example, to compare two builds, one of which with the default :ref:`CONFIG_COMPILER_OPTIMIZATION` setting ``Debug (-Og)`` configuration while another with ``Optimize for size (-Os)``: - -.. code-block:: bash - - $ python -m esp_idf_size --diff build_Og/https_request.map build_Os/https_request.map - MAP file: build_Os/https_request.map - MAP file: build_Og/https_request.map - Difference is counted as - , i.e. a positive number means that is larger. - Total sizes of : Difference - DRAM .data size: 14516 bytes 14956 -440 - DRAM .bss size: 15792 bytes 15808 -16 - Used static DRAM: 30308 bytes ( 150428 available, 16.8% used) 30764 -456 ( +456 available, +0 total) - Used static IRAM: 78498 bytes ( 52574 available, 59.9% used) 83918 -5420 ( +5420 available, +0 total) - Flash code: 509183 bytes 559943 -50760 - Flash rodata: 170592 bytes 176736 -6144 - Total image size:~ 772789 bytes (.bin may be padded larger) 835553 -62764 - -We can see from the ``Difference`` column that changing this one setting caused the whole binary to be over 60 KB smaller and over 5 KB more RAM is available. - -It is also possible to use the ``diff`` mode to output a table of component-level (static library archive) differences: - -.. note:: - - To get the output in JSON or CSV format using ``esp_idf_size``, it is possible to use the ``--format`` option. - -.. code-block:: bash - - python -m esp_idf_size --archives --diff build_Og/https_request.map build_Oshttps_request.map - -Also at the individual source file level: - -.. code-block:: bash - - python -m esp_idf_size --files --diff build_Og/https_request.map build_Oshttps_request.map - -Other options, like writing the output to a file, are available, pass ``--help`` to see the full list. - -.. _idf-size-linker-failed: - -Showing Size When Linker Fails -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If too much static memory is allocated, the linker will fail with an error such as ``DRAM segment data does not fit``, ``region `iram0_0_seg' overflowed by 44 bytes``, or similar. - -In these cases, ``idf.py size`` will not succeed either. However, it is possible to run ``esp_idf_size`` manually to view the **partial static memory usage**. The memory usage will miss the variables that could not be linked, so there still appears to be some free space. - -The map file argument is ``.map`` in the build directory. - -.. code-block:: bash - - python -m esp_idf_size build/project_name.map - -It is also possible to view the equivalent of ``size-components`` or ``size-files`` output: - -.. code-block:: bash - - python -m esp_idf_size --archives build/project_name.map - python -m esp_idf_size --files build/project_name.map +To optimize both the firmware binary size and the memory usage, it is necessary to measure statically-allocated RAM (``data``, ``bss``), code (``text``), and read-only data (``rodata``) in your project. The :ref:`idf.py` sub-commands ``size``, ``size-components``, and ``size-files`` can be used to examine statically-allocated RAM usage at different levels of detail. For more information, please see the :doc:`/api-guides/tools/idf-size` tool. .. _linker-map-file: Linker Map File -^^^^^^^^^^^^^^^ +--------------- .. note:: diff --git a/docs/en/api-guides/tools/idf-size.rst b/docs/en/api-guides/tools/idf-size.rst new file mode 100644 index 00000000000..d456f5392e0 --- /dev/null +++ b/docs/en/api-guides/tools/idf-size.rst @@ -0,0 +1,266 @@ +******** +IDF Size +******** + +IDF Size is a tool for analyzing statically-allocated memory in ESP-IDF project. The main functionality is provided by the esp-idf-size_ Python package, while :ref:`idf.py` offers a more user-friendly and higher-level interface through the ``size``, ``size-components``, and ``size-files`` sub-commands. These sub-commands allow you to specify various options, such as the report's output format. For more details, please use the ``--help`` option. ESP-IDF also includes a handy ``idf_size.py`` wrapper to invoke the esp-idf-size_ Python module. For more information, use the command ``idf_size.py --help``. + +Size Summary ``idf.py size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This output provides a summary of the statically-allocated memory for different memory types in the firmware binary: + +.. code-block:: bash + + $ idf.py size + Memory Type Usage Summary + ┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Memory Type/Section ┃ Used [bytes] ┃ Used [%] ┃ Remain [bytes] ┃ Total [bytes] ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ Flash Code │ 80666 │ 2.41 │ 3261638 │ 3342304 │ + │ .text │ 80666 │ 2.41 │ │ │ + │ IRAM │ 51835 │ 39.55 │ 79237 │ 131072 │ + │ .text │ 50807 │ 38.76 │ │ │ + │ .vectors │ 1027 │ 0.78 │ │ │ + │ Flash Data │ 38224 │ 0.91 │ 4156048 │ 4194272 │ + │ .rodata │ 37968 │ 0.91 │ │ │ + │ .appdesc │ 256 │ 0.01 │ │ │ + │ DRAM │ 11236 │ 6.22 │ 169500 │ 180736 │ + │ .data │ 8988 │ 4.97 │ │ │ + │ .bss │ 2248 │ 1.24 │ │ │ + │ RTC SLOW │ 24 │ 0.29 │ 8168 │ 8192 │ + │ .rtc_slow_reserved │ 24 │ 0.29 │ │ │ + └───────────────────────┴──────────────┴──────────┴────────────────┴───────────────┘ + Total image size: 179712 bytes (.bin may be padded larger) + +Espressif chips include various :doc:`/api-guides/memory-types`, which are detailed in the `Technical Reference Manual (TRM) <{IDF_TARGET_TRM_EN_URL}>`__. These memory types are listed in the ``Memory Type`` column, along with the ELF ``Sections`` that are loaded into each type. The ``Used`` columns display the memory usage for each specific memory type or section. The ``Remain`` column indicates the remaining available memory for the specified memory type. The ``Total`` column shows the total available memory for that memory type, based on the memory region sizes defined in the linker script that map into the memory type. + +.. note:: + + The ``Total`` memory available for each memory type, like ``IRAM``, is determined by the memory region sizes specified in the link map file, which is generated by the linker script, with the MEMORY command, during the build process. The esp-idf-size tool includes YAML files for each target, detailing memory type ranges based on the TRM. The memory ranges from the link map file are mapped to these memory type ranges. This process calculates the total memory available for different memory types. Note that the total available size may differ from what is stated in the TRM, as some memory portions may be reserved for purposes such as the bootloader or cache, depending on the configuration. The remaining memory is calculated by subtracting the sizes of output ``Sections`` loaded to the specific memory type from the ``Total`` size. + +.. note:: + + Certain memory types might map to the same hardware memory. On some targets, ``IRAM`` and ``DRAM`` could be mapped to the same hardware memory but at different virtual addresses, accessible through data and instruction buses. These memory types are referred to as ``DIRAM`` in the ``Memory Type`` column. + +Below is a description of the most interesting memory types and output sections. Please note that all output sections with a non-zero size are included in the summary. Their names are determined by the output section names specified in the linker script. + +- ``DRAM``: Total amount of DRAM allocated at compile time. ``Remain`` indicates the amount of DRAM left to be used as heap memory at runtime. Note that due to meta data overhead, implementation constraints, and startup heap allocations, the actual size of the DRAM heap is smaller. + + - ``.data``: Amount of DRAM allocated at compile time for the ``.data`` (i.e., all statically allocated variables that are initialized to non-zero values). ``.data`` also consumes space in the binary image to store the non-zero initialization values. + + - ``.bss``: Amount of DRAM allocated at compile time for ``.bss`` (i.e., all statically allocated variables that are initialized to zero). ``.bss`` does not consume extra space in flash. + +- ``IRAM``: Total amount of IRAM allocated at compile time. ``Remain`` indicates the amount of IRAM left to be used as heap memory at runtime. Note that due to meta data overhead, implementation constraints, and startup heap allocations, the actual size of the IRAM heap is smaller. + + - ``.text``: Amount of IRAM used for ``.text`` (i.e., all code that is executed from :ref:`IRAM `). ``.text`` also consumes space in the binary image as the code is initially stored there and is then copied over to IRAM on startup. + +- ``Flash Code``: Code executed from flash. + + - ``.text``: Amount of flash used for ``.text`` (i.e., all code that is executed via the flash cache, see :ref:`IROM `). +- ``Flash Data``: Data stored in flash. + + - ``.rodata``: Amount of flash used for ``.rodata`` (i.e., read-only data that is loaded via the flash cache, see :ref:`DROM `). + +- ``Total image size`` is the estimated total size of the binary file. + +Component Usage Summary ``idf.py size-components`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The summary output from ``idf.py size`` lacks sufficient detail to identify the primary cause of excessive binary size. For a more detailed analysis, use ``idf.py size-components``, which indicates the contribution of each static library archive to the final binary size. + +.. code-block:: bash + + $ idf.py size-components + Per-archive contributions to ELF file + ┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ + ┃ Archive File ┃ Total Size ┃ DRAM ┃ .bss ┃ .data ┃ IRAM ┃ .text ┃ .vectors ┃ Flash Code ┃ .text ┃ Flash Data ┃ .rodata ┃ .appdesc ┃ RTC SLOW ┃ .rtc_slow_reserved ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩ + │ libnet80211.a │ 116712 │ 9454 │ 8393 │ 1061 │ 5310 │ 5310 │ 0 │ 89698 │ 89698 │ 12250 │ 12250 │ 0 │ 0 │ 0 │ + │ libmbedcrypto.a │ 105863 │ 141 │ 81 │ 60 │ 0 │ 0 │ 0 │ 71251 │ 71251 │ 34471 │ 34471 │ 0 │ 0 │ 0 │ + │ liblwip.a │ 85394 │ 2470 │ 2458 │ 12 │ 0 │ 0 │ 0 │ 79486 │ 79486 │ 3438 │ 3438 │ 0 │ 0 │ 0 │ + │ libpp.a │ 66484 │ 3915 │ 1444 │ 2471 │ 20004 │ 20004 │ 0 │ 37714 │ 37714 │ 4851 │ 4851 │ 0 │ 0 │ 0 │ + │ libc.a │ 59525 │ 576 │ 316 │ 260 │ 0 │ 0 │ 0 │ 55513 │ 55513 │ 3436 │ 3436 │ 0 │ 0 │ 0 │ + │ libesp_app_format.a │ 53209 │ 10 │ 10 │ 0 │ 0 │ 0 │ 0 │ 417 │ 417 │ 52782 │ 52526 │ 256 │ 0 │ 0 │ + │ libwpa_supplicant.a │ 45251 │ 1241 │ 1233 │ 8 │ 0 │ 0 │ 0 │ 42315 │ 42315 │ 1695 │ 1695 │ 0 │ 0 │ 0 │ + │ libphy.a │ 44360 │ 1229 │ 637 │ 592 │ 8922 │ 8922 │ 0 │ 34209 │ 34209 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libfreertos.a │ 21108 │ 3841 │ 741 │ 3100 │ 15594 │ 15594 │ 0 │ 467 │ 467 │ 1206 │ 1206 │ 0 │ 0 │ 0 │ + │ libesp_hw_support.a │ 15147 │ 256 │ 96 │ 160 │ 5654 │ 5654 │ 0 │ 8264 │ 8264 │ 949 │ 949 │ 0 │ 24 │ 24 │ + │ libnvs_flash.a │ 14522 │ 24 │ 24 │ 0 │ 0 │ 0 │ 0 │ 14250 │ 14250 │ 248 │ 248 │ 0 │ 0 │ 0 │ + │ libesp_system.a │ 13304 │ 793 │ 313 │ 480 │ 4267 │ 4267 │ 0 │ 7575 │ 7575 │ 669 │ 669 │ 0 │ 0 │ 0 │ + │ libhal.a │ 13078 │ 4000 │ 8 │ 3992 │ 5810 │ 5810 │ 0 │ 3143 │ 3143 │ 125 │ 125 │ 0 │ 0 │ 0 │ + │ libheap.a │ 12009 │ 12 │ 8 │ 4 │ 7298 │ 7298 │ 0 │ 3109 │ 3109 │ 1590 │ 1590 │ 0 │ 0 │ 0 │ + │ libspi_flash.a │ 11613 │ 1348 │ 24 │ 1324 │ 8932 │ 8932 │ 0 │ 865 │ 865 │ 468 │ 468 │ 0 │ 0 │ 0 │ + │ libesp_driver_uart.a │ 7255 │ 228 │ 32 │ 196 │ 0 │ 0 │ 0 │ 6434 │ 6434 │ 593 │ 593 │ 0 │ 0 │ 0 │ + │ libesp_netif.a │ 5954 │ 33 │ 29 │ 4 │ 0 │ 0 │ 0 │ 5758 │ 5758 │ 163 │ 163 │ 0 │ 0 │ 0 │ + │ libvfs.a │ 4180 │ 236 │ 44 │ 192 │ 0 │ 0 │ 0 │ 3757 │ 3757 │ 187 │ 187 │ 0 │ 0 │ 0 │ + │ libesp_mm.a │ 4003 │ 160 │ 124 │ 36 │ 1002 │ 1002 │ 0 │ 2627 │ 2627 │ 214 │ 214 │ 0 │ 0 │ 0 │ + │ libesp_wifi.a │ 3919 │ 527 │ 47 │ 480 │ 357 │ 357 │ 0 │ 2993 │ 2993 │ 42 │ 42 │ 0 │ 0 │ 0 │ + │ libesp_timer.a │ 3471 │ 56 │ 24 │ 32 │ 1621 │ 1621 │ 0 │ 1659 │ 1659 │ 135 │ 135 │ 0 │ 0 │ 0 │ + │ libxtensa.a │ 3412 │ 1044 │ 0 │ 1044 │ 2213 │ 1789 │ 424 │ 119 │ 119 │ 36 │ 36 │ 0 │ 0 │ 0 │ + │ libnewlib.a │ 3352 │ 360 │ 200 │ 160 │ 1535 │ 1535 │ 0 │ 1346 │ 1346 │ 111 │ 111 │ 0 │ 0 │ 0 │ + │ libesp_event.a │ 3137 │ 4 │ 4 │ 0 │ 0 │ 0 │ 0 │ 2992 │ 2992 │ 141 │ 141 │ 0 │ 0 │ 0 │ + │ libesp_phy.a │ 2400 │ 53 │ 36 │ 17 │ 235 │ 235 │ 0 │ 1868 │ 1868 │ 244 │ 244 │ 0 │ 0 │ 0 │ + │ libbootloader_support.a │ 1939 │ 0 │ 0 │ 0 │ 1805 │ 1805 │ 0 │ 94 │ 94 │ 40 │ 40 │ 0 │ 0 │ 0 │ + │ libesp_partition.a │ 1865 │ 8 │ 8 │ 0 │ 0 │ 0 │ 0 │ 1689 │ 1689 │ 168 │ 168 │ 0 │ 0 │ 0 │ + │ libesp_common.a │ 1793 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 51 │ 51 │ 1742 │ 1742 │ 0 │ 0 │ 0 │ + │ liblog.a │ 1706 │ 280 │ 272 │ 8 │ 276 │ 276 │ 0 │ 1102 │ 1102 │ 48 │ 48 │ 0 │ 0 │ 0 │ + │ libefuse.a │ 1672 │ 64 │ 4 │ 60 │ 0 │ 0 │ 0 │ 1427 │ 1427 │ 181 │ 181 │ 0 │ 0 │ 0 │ + │ libsoc.a │ 1540 │ 0 │ 0 │ 0 │ 37 │ 37 │ 0 │ 39 │ 39 │ 1464 │ 1464 │ 0 │ 0 │ 0 │ + │ libstdc++.a │ 1502 │ 21 │ 17 │ 4 │ 0 │ 0 │ 0 │ 1282 │ 1282 │ 199 │ 199 │ 0 │ 0 │ 0 │ + │ libesp_ringbuf.a │ 1121 │ 0 │ 0 │ 0 │ 1024 │ 1024 │ 0 │ 0 │ 0 │ 97 │ 97 │ 0 │ 0 │ 0 │ + │ libmain.a │ 1027 │ 8 │ 8 │ 0 │ 0 │ 0 │ 0 │ 964 │ 964 │ 55 │ 55 │ 0 │ 0 │ 0 │ + │ libpthread.a │ 678 │ 20 │ 12 │ 8 │ 0 │ 0 │ 0 │ 604 │ 604 │ 54 │ 54 │ 0 │ 0 │ 0 │ + │ libesp_vfs_console.a │ 599 │ 12 │ 12 │ 0 │ 0 │ 0 │ 0 │ 415 │ 415 │ 172 │ 172 │ 0 │ 0 │ 0 │ + │ libxt_hal.a │ 475 │ 0 │ 0 │ 0 │ 443 │ 443 │ 0 │ 0 │ 0 │ 32 │ 32 │ 0 │ 0 │ 0 │ + │ librtc.a │ 456 │ 0 │ 0 │ 0 │ 456 │ 456 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libcore.a │ 331 │ 33 │ 33 │ 0 │ 0 │ 0 │ 0 │ 255 │ 255 │ 43 │ 43 │ 0 │ 0 │ 0 │ + │ libesp_coex.a │ 277 │ 0 │ 0 │ 0 │ 118 │ 118 │ 0 │ 159 │ 159 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libapp_update.a │ 186 │ 4 │ 4 │ 0 │ 0 │ 0 │ 0 │ 152 │ 152 │ 30 │ 30 │ 0 │ 0 │ 0 │ + │ libesp_rom.a │ 102 │ 0 │ 0 │ 0 │ 102 │ 102 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libgcc.a │ 89 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 89 │ 89 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libcxx.a │ 52 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 52 │ 52 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ libnvs_sec_provider.a │ 5 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 5 │ 5 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ (exe) │ 3 │ 0 │ 0 │ 0 │ 3 │ 0 │ 3 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ + └─────────────────────────┴────────────┴──────┴──────┴───────┴───────┴───────┴──────────┴────────────┴───────┴────────────┴─────────┴──────────┴──────────┴────────────────────┘ + + +Generally, one static library archive is built per component, although some are binary libraries included by a particular component, for example, ``libnet80211.a`` is included by ``esp_wifi`` component. There are also toolchain libraries such as ``libc.a`` and ``libgcc.a`` listed here, these provide Standard C/C++ Library and toolchain built-in functionality. + +If the project is simple and only has a ``main`` component, then all of the project's code will be shown under ``libmain.a``. If the project includes its own components (see :doc:`/api-guides/build-system`), then they will each be shown on a separate line. + +The table is sorted in descending order of the total contribution of the static archive to the binary size. The columns indicate memory types and output sections as detailed in the Size Summary. + +.. note:: + + The ``(exe)`` archive is a special archive that contains object files directly linked into the final binary, meaning they are not part of any archive file. + +.. note:: + + The size of the ``.rodata`` section in the ``Flash Data`` memory type may appear very large for a single archive. This occurs due to linker relaxations. The linker may attempt to combine object file sections with ``MERGE`` and ``STRINGS`` flags from all archives into one to perform tail string optimization. Consequently, one archive may end up with a very large ``.rodata`` section, containing string literals from other archives. This is evident in the ``.rodata`` section of the ``libesp_app_format.a`` archive. + + +Source File Usage Summary ``idf.py size-files`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For even more details, run ``idf.py size-files`` to get a summary of the contribution each object file has made to the final binary size. Each object file corresponds to a single source file. + +.. code-block:: bash + + $ idf.py size-files + Per-file contributions to ELF file + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ + ┃ Object File ┃ Total Size ┃ DRAM ┃ .bss ┃ .data ┃ IRAM ┃ .text ┃ .vectors ┃ Flash Code ┃ .text ┃ Flash Data ┃ .rodata ┃ .appdesc ┃ RTC SLOW ┃ .rtc_slow_reserved ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩ + │ esp_app_desc.c.obj │ 72313 │ 10 │ 10 │ 0 │ 0 │ 0 │ 0 │ 417 │ 417 │ 71886 │ 71630 │ 256 │ 0 │ 0 │ + │ x509_crt_bundle.S.obj │ 67810 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 67810 │ 67810 │ 0 │ 0 │ 0 │ + │ ecp_curves.c.obj │ 36415 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 6875 │ 6875 │ 29540 │ 29540 │ 0 │ 0 │ 0 │ + │ phy_chip_v7.o │ 19384 │ 783 │ 533 │ 250 │ 2186 │ 2186 │ 0 │ 16415 │ 16415 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ wl_cnx.o │ 18567 │ 3891 │ 3889 │ 2 │ 277 │ 277 │ 0 │ 13343 │ 13343 │ 1056 │ 1056 │ 0 │ 0 │ 0 │ + │ ieee80211_output.o │ 15498 │ 27 │ 25 │ 2 │ 2083 │ 2083 │ 0 │ 12840 │ 12840 │ 548 │ 548 │ 0 │ 0 │ 0 │ + │ pp.o │ 14722 │ 1207 │ 53 │ 1154 │ 7286 │ 7286 │ 0 │ 5590 │ 5590 │ 639 │ 639 │ 0 │ 0 │ 0 │ + │ libc_a-vfprintf.o │ 14084 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 13508 │ 13508 │ 576 │ 576 │ 0 │ 0 │ 0 │ + │ phy_chip_v7_cal.o │ 13997 │ 229 │ 54 │ 175 │ 4039 │ 4039 │ 0 │ 9729 │ 9729 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ pm.o │ 13958 │ 532 │ 488 │ 44 │ 3630 │ 3630 │ 0 │ 8823 │ 8823 │ 973 │ 973 │ 0 │ 0 │ 0 │ + │ libc_a-svfprintf.o │ 13753 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 13177 │ 13177 │ 576 │ 576 │ 0 │ 0 │ 0 │ + │ ieee80211_sta.o │ 13711 │ 50 │ 38 │ 12 │ 1443 │ 1443 │ 0 │ 11181 │ 11181 │ 1037 │ 1037 │ 0 │ 0 │ 0 │ + │ ieee80211_ioctl.o │ 13479 │ 120 │ 116 │ 4 │ 271 │ 271 │ 0 │ 11127 │ 11127 │ 1961 │ 1961 │ 0 │ 0 │ 0 │ + │ ieee80211_scan.o │ 12037 │ 327 │ 309 │ 18 │ 0 │ 0 │ 0 │ 11119 │ 11119 │ 591 │ 591 │ 0 │ 0 │ 0 │ + │ ieee80211_hostap.o │ 11970 │ 42 │ 41 │ 1 │ 0 │ 0 │ 0 │ 10898 │ 10898 │ 1030 │ 1030 │ 0 │ 0 │ 0 │ + │ nd6.c.obj │ 11815 │ 940 │ 932 │ 8 │ 0 │ 0 │ 0 │ 10764 │ 10764 │ 111 │ 111 │ 0 │ 0 │ 0 │ + │ phy_chip_v7_ana.o │ 11039 │ 217 │ 50 │ 167 │ 2697 │ 2697 │ 0 │ 8125 │ 8125 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ ieee80211_ht.o │ 11033 │ 5 │ 4 │ 1 │ 1179 │ 1179 │ 0 │ 8466 │ 8466 │ 1383 │ 1383 │ 0 │ 0 │ 0 │ + │ sae.c.obj │ 11003 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 10971 │ 10971 │ 32 │ 32 │ 0 │ 0 │ 0 │ + │ tasks.c.obj │ 10753 │ 712 │ 696 │ 16 │ 9416 │ 9416 │ 0 │ 0 │ 0 │ 625 │ 625 │ 0 │ 0 │ 0 │ + │ libc_a-svfiprintf.o │ 10446 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 9398 │ 9398 │ 1048 │ 1048 │ 0 │ 0 │ 0 │ + │ libc_a-vfiprintf.o │ 10092 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 9516 │ 9516 │ 576 │ 576 │ 0 │ 0 │ 0 │ + │ wpa.c.obj │ 9688 │ 872 │ 872 │ 0 │ 0 │ 0 │ 0 │ 8816 │ 8816 │ 0 │ 0 │ 0 │ 0 │ 0 │ + │ tcp_in.c.obj │ 8904 │ 52 │ 52 │ 0 │ 0 │ 0 │ 0 │ 8698 │ 8698 │ 154 │ 154 │ 0 │ 0 │ 0 │ + [... additional lines removed ...] + + +The table is sorted in descending order of the total contribution of the object files to the binary size. The columns indicate memory types and output sections as detailed in the Size Summary. + +For example, we can see that the file ``x509_crt_bundle.S.o`` contributed 67,810 bytes to the total firmware size, all as ``.rodata`` in flash. Therefore we can guess that this application is using the :doc:`/api-reference/protocols/esp_crt_bundle` feature and not using this feature would save at last this many bytes from the firmware size. + +Some of the object files are linked from binary libraries and therefore you will not find a corresponding source file. To locate which component a source file belongs to, it is generally possible to search in the ESP-IDF source tree or look in the :ref:`linker-map-file` for the full path. + +Comparing Two Binaries +^^^^^^^^^^^^^^^^^^^^^^ + +When making changes that impact binary size, you can use the IDF Size tool to analyze the precise differences in size. The ``--diff`` option can be used with all previously mentioned sub-commands, allowing you to specify a path to a project build for comparison with the current project. + +For example to compare two ``hello_world`` project builds, follow these steps. First, create two copies of the ``hello_world`` project directory. Name the first project directory ``hello_world_Og``. This project will use the default :ref:`CONFIG_COMPILER_OPTIMIZATION` compiler optimization setting ``Debug (-Og)`` and will serve as the ``REFERENCE`` project. Name the second project directory ``hello_world_Os``. This project will use the ``Optimize for size (-Os)`` setting, which can be enabled using ``idf.py menuconfig``. This will be the ``CURRENT`` project. Build both projects. Then, from within the ``hello_world_Os`` project directory, run the following command: + + +.. code-block:: bash + + $ idf.py size --diff ../hello_world_Og + + CURRENT project file: "hello_world_Os/build/hello_world.map" + REFERENCE project file: "hello_world_Og/build/hello_world.map" + Difference is counted as CURRENT - REFERENCE, i.e. a positive number means that CURRENT is larger. + Memory Type Usage Summary + ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + ┃ Memory Type/Section ┃ Used [bytes] ┃ Used [%] ┃ Remain [bytes] ┃ Total [bytes] ┃ + ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ + │ Flash Code │ 74498 -6168 │ 2.23 -0.18 │ 3267806 +6168 │ 3342304 0 │ + │ .text │ 74498 -6168 │ 2.23 -0.18 │ │ │ + │ IRAM │ 45539 -6296 │ 34.74 -4.8 │ 85533 +6296 │ 131072 0 │ + │ .text │ 44511 -6296 │ 33.96 -4.8 │ │ │ + │ Flash Data │ 35784 -2440 │ 0.85 -0.06 │ 4158488 +2440 │ 4194272 0 │ + │ .rodata │ 35528 -2440 │ 0.85 -0.06 │ │ │ + │ DRAM │ 10844 -392 │ 6.0 -0.22 │ 169892 +392 │ 180736 0 │ + │ .data │ 8612 -376 │ 4.76 -0.21 │ │ │ + │ .bss │ 2232 -16 │ 1.23 -0.01 │ │ │ + └─────────────────────┴──────────────┴──────────────┴────────────────┴────────────────┘ + Total image size: 164432 -15280 bytes (.bin may be padded larger) + +In addition to the previously mentioned Size Summary example, each column now also shows the size differences. Each difference is shown as ``CURRENT - REFERENCE``, meaning the current project sizes minus the sizes in the project specified with the `--diff` option. In this example, the final binary image of the ``hello_world_Os`` project is 15,280 bytes smaller than that of the ``hello_world_Og`` project. Additionally, the ``hello_world_Os`` project uses 6,168 bytes less in `Flash Code` memory, leaving 6,168 bytes more available in ``Flash Code``, with no difference in the total available memory. + +You can also use the diff mode to generate a table showing the differences at the component level (static library archive): + +.. code-block:: bash + + $ idf.py size-components --diff ../hello_world_Og + +Additionally, at the level of each individual source file: + +.. code-block:: bash + + $ idf.py size-files --diff ../hello_world_Og + +.. _idf-size-linker-failed: + +Showing Size When Linker Fails +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If too much static memory is allocated, the linker will fail with an error such as ``DRAM segment data does not fit``, ``region `iram0_0_seg' overflowed by 44 bytes``, or similar. + +In these cases, ``idf.py size`` will also fail. However, you can run ``idf_size.py``, which is a convenient wrapper that allows you to call ``esp-idf-size`` directly from within the ESP-IDF environment and see the partial static memory usage. The ``idf_size.py`` script requires a link map file as an argument, which is located in the project's build directory as ``.map``. + +.. code-block:: bash + + $ idf_size.py .map + warning: DRAM overflow detected!: output section or its part .dram0.bss(addr: 1073422848, size: 2240) does not fit into any memory region and will be assigned to the preceding dram0_0_seg memory region + warning: DRAM overflow detected!: output section or its part .dram0.data(addr: 1073414144, size: 8704) does not fit into any memory region and will be assigned to the preceding dram0_0_seg memory region + Memory Type Usage Summary + ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Memory Type/Section ┃ Used [bytes] ┃ Used [%] ┃ Remain [bytes] ┃ Total [bytes] ┃ + ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ Flash Code │ 79759 │ 2.39 │ 3262545 │ 3342304 │ + │ .text │ 79759 │ 2.39 │ │ │ + │ IRAM │ 51106 │ 38.99 │ 79966 │ 131072 │ + │ .text │ 50079 │ 38.21 │ │ │ + │ .vectors │ 1027 │ 0.78 │ │ │ + │ Flash Data │ 38576 │ 0.92 │ 4155696 │ 4194272 │ + │ .rodata │ 38320 │ 0.91 │ │ │ + │ .appdesc │ 256 │ 0.01 │ │ │ + │ DRAM │ 10944 │ 0 │ -10944 │ 0 │ + │ .data_overflow │ 8704 │ 0 │ │ │ + │ .bss_overflow │ 2240 │ 0 │ │ │ + └─────────────────────┴──────────────┴──────────┴────────────────┴───────────────┘ + Total image size: 178145 bytes (.bin may be padded larger) + +Sections that do not fit into the memory region will have the suffix ``_overflow``. + +.. _esp-idf-size: https://github.com/espressif/esp-idf-size diff --git a/docs/en/api-guides/tools/index.rst b/docs/en/api-guides/tools/index.rst index 2f3251c3a24..1b25030209f 100644 --- a/docs/en/api-guides/tools/index.rst +++ b/docs/en/api-guides/tools/index.rst @@ -11,4 +11,5 @@ Tools idf-component-manager idf-clang-tidy idf-tools + idf-size :esp32 or esp32c3: qemu diff --git a/docs/en/api-reference/peripherals/clk_tree.rst b/docs/en/api-reference/peripherals/clk_tree.rst index 1b43c0e7c4b..d54b6bbbcc0 100644 --- a/docs/en/api-reference/peripherals/clk_tree.rst +++ b/docs/en/api-reference/peripherals/clk_tree.rst @@ -7,7 +7,7 @@ Clock Tree {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index 9e28cc92d28..b5aac22a19d 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -150,6 +150,27 @@ Once the :cpp:type:`i2c_device_config_t` structure is populated with mandatory p i2c_master_dev_handle_t dev_handle; ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); +Get I2C master handle via port +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Given that i2c master handle has been initialized in some module(e.g. an audio module), an another module(e.g. a video module) is not convenient to reused the handle. We have a helper function, :cpp:func:`i2c_master_get_bus_handle` for getting the initialized handle via port. However, please make sure the handle has already been initialized ahead of time. Otherwise an error would be reported. + +.. code:: c + + // Source File 1 + #include "driver/i2c_master.h" + i2c_master_bus_handle_t bus_handle; + i2c_master_bus_config_t i2c_mst_config = { + ... // same as others + }; + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + // Source File 2 + #include "esp_private/i2c_platform.h" + #include "driver/i2c_master.h" + i2c_master_bus_handle_t handle; + ESP_ERROR_CHECK(i2c_master_get_bus_handle(0, &handle)); + .. only:: SOC_LP_I2C_SUPPORTED Install I2C master bus with LP I2C Peripheral diff --git a/docs/en/api-reference/peripherals/lcd/spi_lcd.rst b/docs/en/api-reference/peripherals/lcd/spi_lcd.rst index f8fa859c5aa..8f254ca9d9a 100644 --- a/docs/en/api-reference/peripherals/lcd/spi_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/spi_lcd.rst @@ -25,6 +25,8 @@ SPI Interfaced LCD - :cpp:member:`esp_lcd_panel_io_spi_config_t::spi_mode` sets the SPI mode. The LCD driver uses this mode to communicate with the LCD. For the meaning of the SPI mode, please refer to the :doc:`SPI Master API doc `. - :cpp:member:`esp_lcd_panel_io_spi_config_t::lcd_cmd_bits` and :cpp:member:`esp_lcd_panel_io_spi_config_t::lcd_param_bits` set the bit width of the command and parameter that recognized by the LCD controller chip. This is chip specific, you should refer to your LCD spec in advance. - :cpp:member:`esp_lcd_panel_io_spi_config_t::trans_queue_depth` sets the depth of the SPI transaction queue. A bigger value means more transactions can be queued up, but it also consumes more memory. + - :cpp:member:`esp_lcd_panel_io_spi_config_t::cs_ena_pretrans` sets the amount of SPI bit-cycles which the cs should be activated before the transmission (0-16). + - :cpp:member:`esp_lcd_panel_io_spi_config_t::cs_ena_posttrans` sets the amount of SPI bit-cycles which the cs should stay active after the transmission (0-16). .. code-block:: c diff --git a/docs/en/api-reference/peripherals/ledc.rst b/docs/en/api-reference/peripherals/ledc.rst index cce6b155cd5..6595a5aa9c1 100644 --- a/docs/en/api-reference/peripherals/ledc.rst +++ b/docs/en/api-reference/peripherals/ledc.rst @@ -166,7 +166,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f - ~ 17.5 MHz - Dynamic Frequency Scaling compatible, Light sleep compatible * - XTAL_CLK - - 48/40 MHz + - 48 MHz - Dynamic Frequency Scaling compatible .. only:: esp32c6 diff --git a/docs/en/api-reference/peripherals/pcnt.rst b/docs/en/api-reference/peripherals/pcnt.rst index 688417ffc59..99e44fe7bac 100644 --- a/docs/en/api-reference/peripherals/pcnt.rst +++ b/docs/en/api-reference/peripherals/pcnt.rst @@ -25,6 +25,7 @@ Description of the PCNT functionality is divided into the following sections: - :ref:`pcnt-resource-allocation` - covers how to allocate PCNT units and channels with properly set of configurations. It also covers how to recycle the resources when they finished working. - :ref:`pcnt-setup-channel-actions` - covers how to configure the PCNT channel to behave on different signal edges and levels. - :ref:`pcnt-watch-points` - describes how to configure PCNT watch points (i.e., tell PCNT unit to trigger an event when the count reaches a certain value). + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :ref:`pcnt-step-notify` - describes how to configure PCNT watch step (i.e., tell PCNT unit to trigger an event when the count increment reaches a certain value). - :ref:`pcnt-register-event-callbacks` - describes how to hook your specific code to the watch point event callback function. - :ref:`pcnt-set-glitch-filter` - describes how to enable and set the timing parameters for the internal glitch filter. :SOC_PCNT_SUPPORT_CLEAR_SIGNAL: - :ref:`pcnt-set-clear-signal` - describes how to set the parameters for the external clear signal. @@ -47,9 +48,13 @@ Install PCNT Unit To install a PCNT unit, there is a configuration structure that needs to be given in advance: :cpp:type:`pcnt_unit_config_t`: -- :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit` specify the range for the internal hardware counter. The counter will reset to zero automatically when it crosses either the high or low limit. -- :cpp:member:`pcnt_unit_config_t::accum_count` sets whether to create an internal accumulator for the counter. This is helpful when you want to extend the counter's width, which by default is 16 bit at most, defined in the hardware. See also :ref:`pcnt-compensate-overflow-loss` for how to use this feature to compensate the overflow loss. -- :cpp:member:`pcnt_unit_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. +.. list:: + + - :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit` specify the range for the internal hardware counter. The counter will reset to zero automatically when it crosses either the high or low limit. + - :cpp:member:`pcnt_unit_config_t::accum_count` sets whether to create an internal accumulator for the counter. This is helpful when you want to extend the counter's width, which by default is 16 bit at most, defined in the hardware. See also :ref:`pcnt-compensate-overflow-loss` for how to use this feature to compensate the overflow loss. + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_up` Configure whether to enable watch step to count in the positive direction. + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_down` Configure whether to enable watch step to count in the negative direction. + - :cpp:member:`pcnt_unit_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. .. note:: @@ -141,7 +146,36 @@ It is recommended to remove the unused watch point by :cpp:func:`pcnt_unit_remov Due to the hardware limitation, after adding a watch point, you should call :cpp:func:`pcnt_unit_clear_count` to make it take effect. -.. _pcnt-register-event-callbacks: +.. only:: SOC_PCNT_SUPPORT_STEP_NOTIFY + + .. _pcnt-step-notify: + + Watch Step + ^^^^^^^^^^^ + + PCNT unit can be configured to watch a specific value increment (can be positive or negative) that you are interested in. The function of watching value increment is also called **Watch Step**. To install watch step requires enabling :cpp:member:`pcnt_unit_config_t::en_step_notify_up` or :cpp:member:`pcnt_unit_config_t::en_step_notify_down`. The step interval itself can not exceed the range set in :cpp:type:`pcnt_unit_config_t` by :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit`.When the counter increment reaches step interval, a watch event will be triggered and notify you by interrupt if any watch event callback has ever registered in :cpp:func:`pcnt_unit_register_event_callbacks`. See :ref:`pcnt-register-event-callbacks` for how to register event callbacks. + + The watch step can be added and removed by :cpp:func:`pcnt_unit_add_watch_step` and :cpp:func:`pcnt_unit_remove_watch_step`. You can not add multiple watch step, otherwise it will return error :c:macro:`ESP_ERR_INVALID_STATE`。 + + It is recommended to remove the unused watch step by :cpp:func:`pcnt_unit_remove_watch_step` to recycle the watch step resources. + + .. note:: + + When a watch step and a watch point are triggered at the same time (i.e. at the same absolute point), the callback function only gets called by once. + The step interval must be a divisor of :cpp:member:`pcnt_unit_config_t::low_limit` or :cpp:member:`pcnt_unit_config_t::high_limit`. + + .. code:: c + + // add positive direction watch step with 100 step intervals + ESP_ERROR_CHECK(pcnt_unit_add_watch_step(pcnt_unit, 100)); + + .. _pcnt-register-event-callbacks: + +.. only:: not SOC_PCNT_SUPPORT_STEP_NOTIFY + + .. _pcnt-register-event-callbacks: + + Register Event Callbacks ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -152,10 +186,10 @@ When PCNT unit reaches any enabled watch point, specific event will be generated You can save their own context to :cpp:func:`pcnt_unit_register_event_callbacks` as well, via the parameter ``user_ctx``. This user data will be directly passed to the callback functions. -In the callback function, the driver will fill in the event data of specific event. For example, the watch point event data is declared as :cpp:type:`pcnt_watch_event_data_t`: +In the callback function, the driver will fill in the event data of specific event. For example, the watch point event or watch step event data is declared as :cpp:type:`pcnt_watch_event_data_t`: -- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` saves the watch point value that triggers the event. -- :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` saves how the PCNT unit crosses the zero point in the latest time. The possible zero cross modes are listed in the :cpp:type:`pcnt_unit_zero_cross_mode_t`. Usually different zero cross mode means different **counting direction** and **counting step size**. +- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` saves the count value when the event triggered. +- :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` saves how the PCNT unit crosses the zero point in the latest time. The possible zero cross modes are listed in the :cpp:type:`pcnt_unit_zero_cross_mode_t`. Usually different zero cross mode means different **counting direction** and **counting step size**. Registering callback function results in lazy installation of interrupt service, thus this function should only be called before the unit is enabled by :cpp:func:`pcnt_unit_enable`. Otherwise, it can return :c:macro:`ESP_ERR_INVALID_STATE` error. @@ -278,8 +312,11 @@ Compensate Overflow Loss The internal hardware counter will be cleared to zero automatically when it reaches high or low limit. If you want to compensate for that count loss and extend the counter's bit-width, you can: +.. list:: + 1. Enable :cpp:member:`pcnt_unit_config_t::accum_count` when installing the PCNT unit. - 2. Add the high/low limit as the :ref:`pcnt-watch-points`. + :SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. Add the high/low limit as the :ref:`pcnt-watch-points` or add watch step as the :ref:`pcnt-step-notify`. + :not SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. Add the high/low limit as the :ref:`pcnt-watch-points`. 3. Now, the returned count value from the :cpp:func:`pcnt_unit_get_count` function not only reflects the hardware's count value, but also accumulates the high/low overflow loss to it. .. note:: diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index e8181236c6c..6db75246cf7 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -19,7 +19,7 @@ The SPI0/1 bus is shared between the instruction & data cache (for firmware exec .. only:: SOC_SPIRAM_XIP_SUPPORTED - On {IDF_TARGET_NAME}, the config options :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` (disabled by default) and :ref:`CONFIG_SPIRAM_RODATA` (disabled by default) allow the cache to read/write PSRAM concurrently with SPI1 operations. See :ref:`xip_from_psram` for more details. + On {IDF_TARGET_NAME}, the config options :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` (disabled by default) allows the cache to read/write PSRAM concurrently with SPI1 operations. See :ref:`xip_from_psram` for more details. If these options are disabled, the caches must be disabled while reading/writing/erasing operations. There are some constraints using driver on the SPI1 bus, see :ref:`impact_disabled_cache`. These constraints will cause more IRAM/DRAM usages. @@ -40,7 +40,7 @@ Under this condition, all CPUs should always execute code and access data from i .. note:: - When :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA` are both enabled, these APIs will not disable the caches. + When :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` is enabled, these APIs will not disable the caches. .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES diff --git a/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc b/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc index d0af4a89be4..e4e0a6acb38 100644 --- a/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc +++ b/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc @@ -3,10 +3,8 @@ XIP from PSRAM Feature ---------------------- -If :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` is enabled, the flash ``.text`` sections (used for instructions) will be placed in PSRAM. +If :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` is enabled, the flash ``.text`` sections (used for instructions) and the flash ``.rodata`` sections (used for read only data) will be placed in PSRAM. -If :ref:`CONFIG_SPIRAM_RODATA` is enabled, the flash ``.rodata`` sections (used for read only data) will be placed in PSRAM. - -The corresponding virtual memory range will be re-mapped to PSRAM. +The corresponding virtual memory range will be mapped to PSRAM. If both of the above options are enabled, the Cache won't be disabled during an SPI1 Flash operation. You don't need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM. diff --git a/docs/en/api-reference/peripherals/touch_element.rst b/docs/en/api-reference/peripherals/touch_element.rst index 18bc2a377b2..8be2d2ecdcc 100644 --- a/docs/en/api-reference/peripherals/touch_element.rst +++ b/docs/en/api-reference/peripherals/touch_element.rst @@ -443,7 +443,7 @@ The Touch Element Wakeup example is available in `system/light_sleep` directory. // ESP_ERROR_CHECK(touch_element_enable_light_sleep(&sleep_config)); ESP_ERROR_CHECK(touch_element_enable_deep_sleep(button_handle[0], &sleep_config)); - // ESP_ERROR_CHECK(touch_element_sleep_enable_wakeup_calibration(button_handle[0], false)); // (optional) Disable wakeup calibration to prevent updating the baseline to a wrong value + // ESP_ERROR_CHECK(touch_element_sleep_enable_wakeup_calibration(button_handle[0], false)); // (optional) Disable wakeup calibration to prevent updating the benchmark to a wrong value touch_element_start(); diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst new file mode 100644 index 00000000000..3b2876a7a4b --- /dev/null +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst @@ -0,0 +1,65 @@ +USB Host External Hub Driver (Ext Hub) +====================================== + +Introduction +------------ + +The External Hub Driver (henceforth referred to as Ext Hub Driver) + +Requirements +------------ + +USB Specification Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Chapter 11 of the USB 2.0 specification outlines some aspects, when a USB Hub device is attached to a powered port. + +The design of the Ext Driver takes into consideration the following: + +- **Connectivity behavior** +- **Power management** +- **Device connect/disconnect detection** +- **Bus fault detection and recovery** +- **High-, full-, and low-speed device support** + +.. note:: + + For more detailed information, please refer to `USB 2.0 Specification `_ > Chapter 11.1 **Overview**. + +Host Stack Requirements +^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to the USB 2.0 specification requirements, the Ext Hub Driver also takes into consideration the requirements set for the overall Host Stack (see :doc:`./usb_host_notes_design`): + +- Ext Hub Driver must not instantiate any tasks/threads +- Ext Hub Driver must be event driven, providing event callbacks and an event processing function +- Ext Hub Driver must use only API from underlying layer (USBH) + +Implementation & Usage +---------------------- + +Host Stack Interaction +^^^^^^^^^^^^^^^^^^^^^^ + +The Ext Hub Driver takes place between USB Host layer and USBH layer, next to the Hub Driver. The Hub Driver and the Ext Hub Driver were split into two Drivers to achieve the goal of logic distinguishing between root Hub and external Hub. + +Device handling +^^^^^^^^^^^^^^^ + +The Ext Hub Driver can be installed via ``ext_hub_install()`` call and uninstalled via ``ext_hub_uninstall()`` call. After installation the Ext Hub provides the following APIs for external Hub addition and removal: + +- ``ext_hub_new_dev()`` which will verify the device class (`HUB_CLASSCODE (09H)`) and, if the device has the Hub class, the Ext Hub Driver: + + - allocates a new device object + - adds it to the external device pool + - starts the process of Hub configuration (retrieving Hub Descriptor, Device status and Hub status) + +- ``ext_hub_dev_gone()`` which will verify the device in the Ext Hub Driver list and start the process of external Hub device removing. + +Events & Processing +^^^^^^^^^^^^^^^^^^^ + +The Ext Hub Driver is completely event driven and all event handling is done via the ``ext_hub_process()`` function. The ``ext_hub_config_t.proc_req_cb`` callback provided on the Ext Hub Driver installation will be called when processing is required. Typically, ``ext_hub_process()`` will be called from the Hub Driver ``hub_process()`` processing function. + +The Ext Hub Driver does not expose any event callback. + diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst index 6b1c6fa9ac0..738ac7a2701 100644 --- a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst @@ -23,6 +23,7 @@ This document is split into the following sections: usb_host_notes_dwc_otg usb_host_notes_usbh usb_host_notes_enum + usb_host_notes_ext_hub Todo: @@ -45,6 +46,10 @@ Features & Limitations **The Host Stack currently supports the following notable features:** +.. only:: esp32p4 + + - Supports HS (High Speed) + - Supports FS (Full Speed) and LS (Low Speed) devices - Supports all transfer types (Control, Bulk, Isochronous, and Interrupt) - Automatically enumerates connected devices @@ -52,5 +57,4 @@ Features & Limitations **The Host Stack currently has the following notable limitations:** -- No HS (High Speed) support - No Hub support (currently only supports a single device) diff --git a/docs/en/api-reference/protocols/esp_tls.rst b/docs/en/api-reference/protocols/esp_tls.rst index d4937a9619a..b0c5c9911ef 100644 --- a/docs/en/api-reference/protocols/esp_tls.rst +++ b/docs/en/api-reference/protocols/esp_tls.rst @@ -208,8 +208,10 @@ The following table shows a typical comparison between WolfSSL and MbedTLS when ECDSA Peripheral with ESP-TLS ----------------------------- - ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to :doc:`ECDSA Guide <../peripherals/ecdsa>` for programming the ECDSA key in the eFuse. + ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to :doc:`ECDSA Guide <../peripherals/ecdsa>` for programming the ECDSA key in the eFuse. + To use ECDSA peripheral with ESP-TLS, set :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` to `true`, and set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the eFuse block ID in which ECDSA private key is stored. + This will enable the use of ECDSA peripheral for private key operations. As the client private key is already present in the eFuse, it needs not be supplied to the :cpp:type:`esp_tls_cfg_t` structure. .. code-block:: c diff --git a/docs/en/api-reference/storage/index.rst b/docs/en/api-reference/storage/index.rst index 2ff6698d708..3e31007594e 100644 --- a/docs/en/api-reference/storage/index.rst +++ b/docs/en/api-reference/storage/index.rst @@ -12,6 +12,8 @@ This section contains reference of the high-level storage APIs. They are based o - :doc:`FAT ` is a standard file system which can be used in SPI flash or on SD/MMC cards - :doc:`Wear Levelling ` library implements a flash translation layer (FTL) suitable for SPI NOR flash. It is used as a container for FAT partitions in flash. +Topics related to :doc:`Storage Security ` are described in separate section. + .. note:: It is suggested to use high-level APIs (``esp_partition`` or file system) instead of low-level driver APIs to access the SPI NOR flash. @@ -33,5 +35,47 @@ This section contains reference of the high-level storage APIs. They are based o spiffs vfs wear-levelling + storage-security.rst + +.. list-table:: Code examples for this API section + :widths: 25 75 + :header-rows: 0 -Code examples for this API section are provided in the :example:`storage` directory of ESP-IDF examples. + * - **Link** + - **Description** + * - :doc:`FAT ` + - + * - :example:`` + - Demonstrates using FATFS over wear leveling on internal flash. + * - :example:`ext_flash_fatfs ` + - Demonstrates using FATFS over wear leveling on external flash. + * - :example:`fatfsgen ` + - Demonstrates the capabilities of Python-based tooling for FATFS images available on host computers. + * - :doc:`Non-Volatile Storage library (NVS) ` + - + * - :example:`nvs_rw_blob ` + - Shows the use of the C-style API to read and write blob data types in NVS flash. + * - :example:`nvs_rw_value ` + - Shows the use of the C-style API to read and write integer data types in NVS flash. + * - :example:`nvs_rw_value_cxx ` + - Shows the use of the C++-style API to read and write integer data types in NVS flash. + * - :example:`nvsgen ` + - Demonstrates how to use the Python-based NVS image generation tool to create an NVS partition image from the contents of a CSV file. + * - :doc:`SPIFFS ` + - + * - :example:`spiffs ` + - Shows the use of the SPIFFS API to initialize the filesystem and work with files using POSIX functions. + * - :example:`spiffsgen ` + - Demonstrates the capabilities of Python-based tooling for SPIFFS images available on host computers. + * - :doc:`Partitions API ` + - + * - :example:`partition_api ` + - Provides an overview of API functions to look up particular partitions, perform basic I/O operations, and use partitions via CPU memory mapping. + * - :example:`parttool ` + - Demonstrates the capabilities of Python-based tooling for partition images available on host computers. + * - :doc:`Virtual File System (VFS) ` + - + * - :example:`littlefs ` + - Shows the use of the LittleFS component to initialize the filesystem and work with a file using POSIX functions. + * - :example:`semihost_vfs ` + - Demonstrates the use of the VFS API to let an ESP-based device access a file on a JTAG-connected host using POSIX functions. diff --git a/docs/en/api-reference/storage/storage-security.rst b/docs/en/api-reference/storage/storage-security.rst new file mode 100644 index 00000000000..496bbfffbc6 --- /dev/null +++ b/docs/en/api-reference/storage/storage-security.rst @@ -0,0 +1,24 @@ +Storage Security +================ + +:link_to_translation:`zh_CN:[中文]` + +Overview of Available Resources +------------------------------- + +Data privacy is achieved by using the :doc:`../../security/flash-encryption` feature. This mechanism is currently used by FATFS and LittleFS and is recommended for new storage type implementations based on the Partitions API. +NVS storage uses a proprietary :doc:`NVS encryption ` implementation. + +Workflows focused on overall system security are described in the :doc:`Host Based Workflows <../../security/host-based-security-workflows>`. +Workflows related to the combination of multiple secured storage components in one project are presented in the :example:`Flash Encryption Example `. + +.. list-table:: Relevant storage security examples + :widths: 25 75 + :header-rows: 0 + + * - **Link** + - **Description** + * - :example:`nvs_encryption_hmac ` + - Demonstrates NVS encryption with an HMAC-based encryption key protection scheme. + * - :example:`flash_encryption ` + - Provides a combined example showing the coexistence of NVS encryption, FATFS encryption, and encrypted custom data access via the Partitions API. Security related workflows for both development and production are also provided. diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index 2fb87648fbd..faf68f80d74 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -304,6 +304,20 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON); + .. only:: SOC_PM_SUPPORT_TOP_PD + + .. note:: + + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode. + + Alternatively,you can use :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` directly in that condition for GPIO wakeup, because the digital IO power domain is being powered off, where the situation is the same as entering Deep-sleep. + + .. only:: not SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode. + .. only:: not SOC_RTCIO_WAKE_SUPPORTED GPIO Wakeup @@ -313,11 +327,13 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi Additionally, IOs that are powered by the VDD3P3_RTC power domain can be used to wake up the chip from Deep-sleep. The wakeup pin and wakeup trigger level can be configured by calling :cpp:func:`esp_deep_sleep_enable_gpio_wakeup`. The function will enable the Deep-sleep wakeup for the selected pin. - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD .. note:: - In Light-sleep mode, setting Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` will invalidate GPIO wakeup. + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, you can use :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` directly for GPIO wakeup, because the digital IO power domain is being powered off, where the situation is the same as entering Deep-sleep. UART Wakeup (Light-sleep Only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-reference/system/ulp-lp-core.rst b/docs/en/api-reference/system/ulp-lp-core.rst index 70e59eb4054..eb190c53cb8 100644 --- a/docs/en/api-reference/system/ulp-lp-core.rst +++ b/docs/en/api-reference/system/ulp-lp-core.rst @@ -103,7 +103,7 @@ To access the ULP LP-Core program variables from the main program, the generated .. note:: - Variables declared in the global scope of the LP-Core program reside in either the ``.bss`` or ``.data`` section of the binary. These sections are initialized when the LP-Core binary is loaded and executed. Accessing these variables from the main program on the HP-Core before the first LP-Core run may result in undefined behavior. + Variables declared in the global scope of the LP-Core program reside in either the ``.bss`` or ``.data`` section of the binary. These sections are initialized when the LP-Core binary is loaded and executed. Accessing these variables from the main program on the HP-Core before the first LP-Core run may result in undefined behavior. Starting the ULP LP-Core Program @@ -168,6 +168,7 @@ To enhance the capabilities of the ULP LP-Core coprocessor, it has access to per * LP IO * LP I2C * LP UART + :SOC_LP_SPI_SUPPORTED: * LP SPI .. only:: CONFIG_ESP_ROM_HAS_LP_ROM @@ -240,6 +241,10 @@ Main CPU API Reference .. include-build-file:: inc/lp_core_i2c.inc .. include-build-file:: inc/lp_core_uart.inc +.. only:: CONFIG_SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/lp_core_spi.inc + LP Core API Reference ~~~~~~~~~~~~~~~~~~~~~~ @@ -250,4 +255,8 @@ LP Core API Reference .. include-build-file:: inc/ulp_lp_core_print.inc .. include-build-file:: inc/ulp_lp_core_interrupts.inc +.. only:: CONFIG_SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/ulp_lp_core_spi.inc + .. _esp-idf-monitor: https://github.com/espressif/esp-idf-monitor diff --git a/docs/en/api-reference/system/ulp-risc-v.rst b/docs/en/api-reference/system/ulp-risc-v.rst index 7b78fca4992..c205f11bac1 100644 --- a/docs/en/api-reference/system/ulp-risc-v.rst +++ b/docs/en/api-reference/system/ulp-risc-v.rst @@ -105,7 +105,7 @@ To access the ULP RISC-V program variables from the main program, the generated .. note:: - Variables declared in the global scope of the ULP RISC-V program reside in either the ``.bss`` or ``.data`` section of the binary. These sections are initialized when the ULP RISC-V binary is loaded and executed. Accessing these variables from the main program on the main CPU before the first ULP RISC-V run may result in undefined behavior. + Variables declared in the global scope of the ULP RISC-V program reside in either the ``.bss`` or ``.data`` section of the binary. These sections are initialized when the ULP RISC-V binary is loaded and executed. Accessing these variables from the main program on the main CPU before the first ULP RISC-V run may result in undefined behavior. Mutual Exclusion diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index 8f4bac790f1..9702f7dad24 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -130,8 +130,8 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y .. toctree:: :maxdepth: 1 - ESP32-C3-DevKitM-1 <../hw-reference/esp32c3/user-guide-devkitm-1> - ESP32-C3-DevKitC-02 <../hw-reference/esp32c3/user-guide-devkitc-02> + ESP32-C3-DevKitM-1 + ESP32-C3-DevKitC-02 .. only:: esp32s3 diff --git a/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst b/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst deleted file mode 100644 index 857ae0bd6cc..00000000000 --- a/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst +++ /dev/null @@ -1,236 +0,0 @@ -=================== -ESP32-C3-DevKitC-02 -=================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide will help you get started with ESP32-C3-DevKitC-02 and will also provide more in-depth information. - -ESP32-C3-DevKitC-02 is an entry-level development board based on `ESP32-C3-WROOM-02 `_, a general-purpose module with 4 MB SPI flash. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions. - -Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-C3-DevKitC-02 on a breadboard. - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitC-02 - :figclass: align-center - - ESP32-C3-DevKitC-02 - -The document consists of the following major sections: - -- `Getting Started`_: Overview of ESP32-C3-DevKitC-02 and hardware/software setup instructions to get started. -- `Hardware Reference`_: More detailed information about the ESP32-C3-DevKitC-02's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-C3-DevKitC-02. -- `Related Documents`_: Links to related documentation. - - -Getting Started -=============== - -This section provides a brief introduction of ESP32-C3-DevKitC-02, instructions on how to do the initial hardware setup and how to flash firmware onto it. - - -Description of Components -------------------------- - -.. _user-guide-c3-devkitc-02-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitC-02 - front - :figclass: align-center - - ESP32-C3-DevKitC-02 - front - -The key components of the board are described in a counter-clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-C3-WROOM-02 - - ESP32-C3-WROOM-02 from Espressif is a powerful and general-purpose module that offers Wi-Fi and Bluetooth Low Energy coexistence. It has a PCB antenna and a 4 MB SPI flash. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - * - 5 V Power On LED - - Turns on when the USB power is connected to the board. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. For details, please see :ref:`user-guide-c3-devkitc-02-v1-header-blocks`. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - Micro-USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-C3 chip. - * - Reset Button - - Press this button to restart the system. - * - USB-to-UART Bridge - - Single USB-to-UART bridge chip provides transfer rates up to 3 Mbps. - * - RGB LED - - Addressable RGB LED, driven by GPIO8. - -Start Application Development ------------------------------ - -Before powering up your ESP32-C3-DevKitC-02, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-C3-DevKitC-02 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an application example into your ESP32-C3-DevKitC-02. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order a few samples, each ESP32-C3-DevKitC-02 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the components of ESP32-C3-DevKitC-02 and their interconnections. - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitC-02 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitC-02 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- Micro-USB Port, default power supply -- 5V and GND pin headers -- 3V3 and GND pin headers - -It is recommended to use the first option: Micro-USB Port. - - -.. _user-guide-c3-devkitc-02-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-c3-devkitc-02-v1-board-front`. The numbering is the same as in the `ESP32-C3-DevKitC-02 Schematic`_ (PDF). - - -J1 -^^^ - -=== ==== ========== =================================== -No. Name Type [1]_ Function -=== ==== ========== =================================== -1 G G Ground -2 3V3 P 3.3 V power supply -3 3V3 P 3.3 V power supply -4 RST I CHIP_PU -5 G G Ground -6 4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -7 5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -8 6 I/O/T GPIO6, FSPICLK, MTCK -9 7 I/O/T GPIO7, FSPID, MTDO -10 G G Ground -11 8 I/O/T GPIO8 [2]_, RGB LED -12 9 I/O/T GPIO9 [2]_ -13 5V P 5 V power supply -14 5V P 5 V power supply -15 G G Ground -=== ==== ========== =================================== - - -J3 -^^^ - -=== ==== ========== ==================================== -No. Name Type [1]_ Function -=== ==== ========== ==================================== -1 G G Ground -2 0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -3 1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -4 2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 3 I/O/T GPIO3, ADC1_CH3 -6 G G Ground -7 10 I/O/T GPIO10, FSPICS0 -8 G G Ground -9 RX I/O/T GPIO20, U0RXD -10 TX I/O/T GPIO21, U0TXD -11 G G Ground -12 18 I/O/T GPIO18, USB_D- -13 19 I/O/T GPIO19, USB_D+ -14 G G Ground -15 G G Ground -=== ==== ========== ==================================== - -.. [1] P: Power supply; I: Input; O: Output; T: High impedance. -.. [2] GPIO2, GPIO8, and GPIO9 are strapping pins of the ESP32-C3 chip. These pins are used to control several chip functions depending on binary voltage values applied to the pins during chip power-up or system reset. For description and application of the strapping pins, please refer to Section Strapping Pins in `ESP32-C3 Datasheet`_. - - -Pin Layout -^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitC-02 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitC-02 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `Build Secure and Cost-effective Connected Devices with ESP32-C3 `_ -* `ESP32-C3 Datasheet`_ (PDF) -* `ESP32-C3-WROOM-02 Datasheet`_ (PDF) -* `ESP32-C3-DevKitC-02 Schematic`_ (PDF) -* `ESP32-C3-DevKitC-02 PCB Layout `_ (PDF) -* `ESP32-C3-DevKitC-02 Dimensions `_ (PDF) -* `ESP32-C3-DevKitC-02 Dimensions source file `_ (DXF) - You can view it with `Autodesk Viewer `_ online - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _ESP32-C3-WROOM-02 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3-wroom-02_datasheet_en.pdf -.. _ESP32-C3-DevKitC-02 Schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITC-02_V1_1_20210126A.pdf diff --git a/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst b/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst deleted file mode 100644 index 2e9cb14e42c..00000000000 --- a/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst +++ /dev/null @@ -1,240 +0,0 @@ -================== -ESP32-C3-DevKitM-1 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide will help you get started with ESP32-C3-DevKitM-1 and will also provide more in-depth information. - -ESP32-C3-DevKitM-1 is an entry-level development board based on `ESP32-C3-MINI-1 `_, a module named for its small size. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions. - -Most of the I/O pins on the ESP32-C3-MINI-1 module are broken out to the pin headers on both sides of this board for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-C3-DevKitM-1 on a breadboard. - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitM-1 - :figclass: align-center - - ESP32-C3-DevKitM-1 - -The document consists of the following major sections: - -- `Getting Started`_: Overview of ESP32-C3-DevKitM-1 and hardware/software setup instructions to get started. -- `Hardware Reference`_: More detailed information about the ESP32-C3-DevKitM-1's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-C3-DevKitM-1. -- `Related Documents`_: Links to related documentation. - - -Getting Started -=============== - -This section provides a brief introduction of ESP32-C3-DevKitM-1, instructions on how to do the initial hardware setup and how to flash firmware onto it. - - -Description of Components -------------------------- - -.. _user-guide-c3-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitM-1 - front - :figclass: align-center - - ESP32-C3-DevKitM-1 - front - -The key components of the board are described in a counter-clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-C3-MINI-1 - - ESP32-C3-MINI-1 is a general-purpose Wi-Fi and Bluetooth Low Energy combo module that comes with a PCB antenna. At the core of this module is `ESP32-C3FN4 `_, a chip that has an embedded flash of 4 MB. Since flash is packaged in the ESP32-C3FN4 chip, rather than integrated into the module, ESP32-C3-MINI-1 has a smaller package size. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - * - 5 V Power On LED - - Turns on when the USB power is connected to the board. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. For details, please see :ref:`user-guide-c3-devkitm-1-v1-header-blocks`. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - Micro-USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-C3FN4 chip. - * - Reset Button - - Press this button to restart the system. - * - USB-to-UART Bridge - - Single USB-UART bridge chip provides transfer rates up to 3 Mbps. - * - RGB LED - - Addressable RGB LED, driven by GPIO8. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-C3-DevKitM-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-C3-DevKitM-1 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an application example onto your ESP32-C3-DevKitM-1. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order one or several samples, each ESP32-C3-DevKitM-1 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the components of ESP32-C3-DevKitM-1 and their interconnections. - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitM-1 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitM-1 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- Micro-USB Port, default power supply -- 5V and GND pin headers -- 3V3 and GND pin headers - -It is recommended to use the first option: Micro-USB Port. - - -.. _user-guide-c3-devkitm-1-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-c3-devkitm-1-v1-board-front`. The numbering is the same as in the `ESP32-C3-DevKitM-1 Schematic`_ (PDF). - - -J1 -^^^ - -=== ==== ========== =================================== -No. Name Type [1]_ Function -=== ==== ========== =================================== -1 GND G Ground -2 3V3 P 3.3 V power supply -3 3V3 P 3.3 V power supply -4 IO2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 IO3 I/O/T GPIO3, ADC1_CH3 -6 GND G Ground -7 RST I CHIP_PU -8 GND G Ground -9 IO0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -10 IO1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -11 IO10 I/O/T GPIO10, FSPICS0 -12 GND G Ground -13 5V P 5 V power supply -14 5V P 5 V power supply -15 GND G Ground -=== ==== ========== =================================== - - -J3 -^^^ - -=== ==== ========== ==================================== -No. Name Type [1]_ Function -=== ==== ========== ==================================== -1 GND G Ground -2 TX I/O/T GPIO21, U0TXD -3 RX I/O/T GPIO20, U0RXD -4 GND G Ground -5 IO9 I/O/T GPIO9 [2]_ -6 IO8 I/O/T GPIO8 [2]_, RGB LED -7 GND G Ground -8 IO7 I/O/T GPIO7, FSPID, MTDO -9 IO6 I/O/T GPIO6, FSPICLK, MTCK -10 IO5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -11 IO4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -12 GND G Ground -13 IO18 I/O/T GPIO18, USB_D- -14 IO19 I/O/T GPIO19, USB_D+ -15 GND G Ground -=== ==== ========== ==================================== - -.. [1] P: Power supply; I: Input; O: Output; T: High impedance. -.. [2] GPIO2, GPIO8, and GPIO9 are strapping pins of the ESP32-C3FN4 chip. These pins are used to control several chip functions depending on binary voltage values applied to the pins during chip power-up or system reset. For description and application of the strapping pins, please refer to Section Strapping Pins in `ESP32-C3 Datasheet`_. - - -Pin Layout -^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitM-1 (click to enlarge) - - ESP32-C3-DevKitM-1 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `Build Secure and Cost-effective Connected Devices with ESP32-C3 `_ -* `ESP32-C3 Datasheet`_ (PDF) -* `ESP32-C3-MINI-1 Datasheet`_ (PDF) -* `ESP32-C3-DevKitM-1 Schematic`_ (PDF) -* `ESP32-C3-DevKitM-1 PCB Layout`_ (PDF) -* `ESP32-C3-DevKitM-1 Dimensions`_ (PDF) -* `ESP32-C3-DevKitM-1 Dimensions source file`_ (DXF) - You can view it with `Autodesk Viewer `_ online - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _ESP32-C3-MINI-1 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf -.. _ESP32-C3-DevKitM-1 Schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITM-1_V1_20200915A.pdf -.. _ESP32-C3-DevKitM-1 PCB Layout: https://dl.espressif.com/dl/schematics/PCB_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 Dimensions: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 Dimensions source file: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.dxf diff --git a/docs/en/migration-guides/release-5.x/5.4/system.rst b/docs/en/migration-guides/release-5.x/5.4/system.rst index df98248613b..ae7414bf5d1 100644 --- a/docs/en/migration-guides/release-5.x/5.4/system.rst +++ b/docs/en/migration-guides/release-5.x/5.4/system.rst @@ -8,3 +8,10 @@ Log - `esp_log_buffer_hex` is deprecated, use `ESP_LOG_BUFFER_HEX` instead. - `esp_log_buffer_char` is deprecated, use `ESP_LOG_BUFFER_CHAR` instead. + +ESP rom +--- + +- All target-specific header files has been moved from `components/esp_rom/include/{target}/` to `/esp_rom/{target}/include/{target}/`, and `components/esp_rom/CMakeLists.txt` has been modified accordingly. If you encounter an error indicating a missing header file, such as ``fatal error: esp32s3/rom/efuse.h: No such file or directory``, try removing the leading relative path from the header file include statement. In your current and future development, when including any header files from the components/esp_rom folder, directly include the header file name without the target-specific relative folder path. +- All target-specific `rom/miniz.h` files are removed because they are deprecated. + diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index 4e24a076bc0..6600c7eba2e 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -55,7 +55,7 @@ Other types of data can be encrypted conditionally: Relevant eFuses --------------- -The flash encryption operation is controlled by various eFuses available on {IDF_TARGET_NAME}. The list of eFuses and their descriptions is given in the table below. The names in eFuse column are also used by espefuse.py tool and idf.py based eFuse commands. For usage in the eFuse API, modify the name by adding ``ESP_EFUSE_``, for example: esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT). +The flash encryption operation is controlled by various eFuses available on {IDF_TARGET_NAME}. The list of eFuses and their descriptions is given in the table below. The names in eFuse column are also used by ``espefuse.py`` tool and ``idf.py`` based eFuse commands. For usage in the eFuse API, modify the name by adding ``ESP_EFUSE_``, for example: esp_efuse_read_field_bit (ESP_EFUSE_DISABLE_DL_ENCRYPT). .. Comment: As text in cells of list-table header rows does not wrap, it is necessary to make 0 header rows and apply bold typeface to the first row. Otherwise, the table goes beyond the html page limits on the right. @@ -164,7 +164,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF * R/W access control is available for all the eFuse bits listed in the table above. * The default value of these bits is 0 after manufacturing. -Read and write access to eFuse bits is controlled by appropriate fields in the registers ``WR_DIS`` and ``RD_DIS``. For more information on {IDF_TARGET_NAME} eFuses, see :doc:`eFuse manager <../api-reference/system/efuse>`. To change protection bits of eFuse field using idf.py, use these two commands: efuse-read-protect and efuse-write-protect (idf.py based aliases of espefuse.py commands write_protect_efuse and read_protect_efuse). Example ``idf.py efuse-write-protect DISABLE_DL_ENCRYPT``. +Read and write access to eFuse bits is controlled by appropriate fields in the registers ``WR_DIS`` and ``RD_DIS``. For more information on {IDF_TARGET_NAME} eFuses, see :doc:`eFuse manager <../api-reference/system/efuse>`. To change protection bits of eFuse field using ``idf.py``, use these two commands: efuse-read-protect and efuse-write-protect (idf.py based aliases of espefuse.py commands write_protect_efuse and read_protect_efuse). Example ``idf.py efuse-write-protect DISABLE_DL_ENCRYPT``. .. only:: esp32c2 @@ -413,7 +413,7 @@ To use a host generated key, take the following steps: idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin KEYPURPOSE - where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``. And ``KEYPURPOSE`` is either ``AES_256_KEY_1``, ``XTS_AES_256_KEY_2``, ``XTS_AES_128_KEY``. See `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_ for a description of the key purposes. + where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``. And ``KEYPURPOSE`` is either ``XTS_AES_256_KEY_1``, ``XTS_AES_256_KEY_2``, ``XTS_AES_128_KEY``. See `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_ for a description of the key purposes. For AES-128 (256-bit key) - ``XTS_AES_128_KEY``: diff --git a/docs/en/security/vulnerabilities.rst b/docs/en/security/vulnerabilities.rst index 32a188891c2..a8629f945e9 100644 --- a/docs/en/security/vulnerabilities.rst +++ b/docs/en/security/vulnerabilities.rst @@ -43,6 +43,17 @@ Security Advisory Concerning the Bluetooth BLUFFS Vulnerability * Impact: Applicable for ESP-IDF * Resolution: Please see advisory for details + +CVE-2023-52160 +~~~~~~~~~~~~~~ + +Security Advisory for PEAP Phase-2 Authentication + +* Espressif Advisory: `AR2024-003`_ +* Impact: Applicable for ESP-IDF +* Resolution: Please see advisory for details + + CVE-2022 -------- @@ -160,5 +171,6 @@ Security Advisory Concerning Wi-Fi Authentication Bypass .. _`AR2023-005`: https://www.espressif.com/sites/default/files/advisory_downloads/AR2023-005%20Security%20Advisory%20Concerning%20Bypassing%20Secure%20Boot%20and%20Flash%20Encryption%20Using%20EMFI%20EN.pdf .. _`AR2023-008`: https://www.espressif.com/sites/default/files/advisory_downloads/AR2023-008%20Security%20Advisory%20for%20WLAN%20FragAttacks%20v1.1%20EN_0.pdf .. _`AR2023-010`: https://www.espressif.com/sites/default/files/advisory_downloads/AR2023-010%20Security%20Advisory%20Concerning%20the%20Bluetooth%20BLUFFS%20Vulnerability%20EN.pdf +.. _`AR2024-003`: https://www.espressif.com/sites/default/files/advisory_downloads/AR2024-003%20Security%20Advisory%20for%20PEAP%20Phase-2%20authentication%20EN.pdf .. _`GHSA-22x6-3756-pfp8` : https://github.com/espressif/esp-idf/security/advisories/GHSA-22x6-3756-pfp8 .. _`GHSA-7f7f-jj2q-28wm` : https://github.com/espressif/esp-idf/security/advisories/GHSA-7f7f-jj2q-28wm diff --git a/docs/zh_CN/COPYRIGHT.rst b/docs/zh_CN/COPYRIGHT.rst index 6da18a6c32f..527b3ce000c 100644 --- a/docs/zh_CN/COPYRIGHT.rst +++ b/docs/zh_CN/COPYRIGHT.rst @@ -1 +1,175 @@ -.. include:: ../en/COPYRIGHT.rst +版权和许可证 +************ + +:link_to_translation:`en:[English]` + +软件版权 +======== + +2015-2023 乐鑫科技享有本代码库中的所有原创源代码版权。源代码根据 LICENSE 文件描述的 Apache License 2.0 进行许可。 + +以下各许可证还包含一些第三方版权代码。 + +如果源代码头文件中指定了版权和许可证信息,则该信息优先于此处的摘要。 + +部分示例使用了未经 Apache 许可的外部组件,请查看每个示例源代码中的版权描述。 + +固件组件 +-------- + +以下这些第三方库包含在 ESP-IDF 生成的应用程序(固件)中。 + +* :component:`Newlib ` 经 BSD 许可证许可,版权归各方所有,如 :component_file:`COPYING.NEWLIB ` 中所述。 + +* :component:`Xtensa 头文件 ` 版权归 2013 Tensilica 公司所有,并根据各头文件中复制的 MIT 许可证进行许可。 + +* FreeRTOS_ (components/freertos) 的原始部分,版权归 2017 亚马逊公司或其附属公司所有,并根据 :component_file:`license.txt ` 中描述的 MIT 许可证进行许可。 + +* LWIP_ (components/lwip) 的原始部分,版权归 2001、2002 瑞典计算机科学研究所所有,根据 :component_file:`COPYING 文件 ` 中描述的 BSD 许可证进行许可。 + +* `wpa_supplicant`_ 版权归 2003-2022 Jouni Malinen 及其他贡献者所有,并根据 BSD 许可证进行许可。 + +* :component_file:`Fast PBKDF2 ` 版权归 2015 Joseph Birr-Pixton 所有,并根据 CC0 公共领域奉献许可证进行许可。 + +* `FreeBSD net80211`_ 版权归 2004-2008 Sam Leffler 和 Errno 咨询公司所有,并根据 BSD 许可证进行许可。 + +* `argtable3`_ 参数解析库版权归 1998-2001、2003-2011、2013 Stewart Heitmann 所有,并根据三条款 BSD 许可证进行许可。argtable3 还包含以下软件组件。详情请参阅 argtable3 :component_file:`LICENSE 文件 `。 + + * C 哈希表库,版权归 2002 Christopher Clark 所有,并根据三条款 BSD 许可证进行许可。 + * Better String 库,版权归 2014 Paul Hsieh 所有,并根据三条款 BSD 许可证进行许可。 + * TCL 库,版权归加州大学董事会、太阳计算机系统有限公司、Scriptics 公司、ActiveState 公司及其他方所有,并根据 TCL/TK 许可证进行许可。 + +* `linenoise`_ 行编辑库版权归 2010-2014 Salvatore Sanfilippo 及 2010-2013 Pieter Noordhuis 所有,根据二条款 BSD 许可证进行许可。 + +* `FatFS`_ 库,版权归 2017 ChaN 所有,并根据 :component_file:`BSD 式条款 ` 进行许可。 + +* `cJSON`_ 库,版权归 2009-2017 Dave Gamble 及 cJSON 库贡献者所有,根据 :component_file:`LICENSE 文件 ` 中描述的 MIT 许可证进行许可。 + +* `micro-ecc`_ 库,版权归 2014 Kenneth MacKay 所有,根据二条款 BSD 许可证进行许可。 + +* `Mbed TLS`_ 库,版权归 2006-2018 安谋控股公司所有,根据 :component_file:`LICENSE 文件 ` 中描述的 Apache License 2.0 进行许可。 + +* `SPIFFS`_ 库,版权归 2013-2017 Peter Andersson 所有,根据 :component_file:`LICENSE 文件 ` 中描述的 MIT 许可证进行许可。 + +* :component_file:`SD/MMC 驱动程序 ` 派生自 `OpenBSD SD/MMC 驱动程序`_,版权归 2006 Uwe Stuehler 所有,并根据 BSD 许可证进行许可。 + +* :component:`ESP-MQTT ` 包 (contiki-mqtt),版权归 2014 Stephen Robinson 和 MQTT-ESP - Tuan PM 所有,根据 :component_file:`LICENSE 文件 ` 中描述的 Apache License 2.0 进行许可。 + +* :component:`BLE Mesh ` 改编自 Zephyr 项目,版权归 2017-2018 英特尔公司所有,并根据 Apache License 2.0 进行许可。 + +* `mynewt-nimble`_,版权归 2015-2018 Apache 软件基金会所有,根据 :component_file:`LICENSE 文件 ` 中描述的 Apache License 2.0 进行许可。 + +* `TLSF 分配器 `_,版权归 2006-2016 Matthew Conte 所有,并根据三条款 BSD 许可证进行许可。 + +* :component:`openthread`,版权归 OpenThread 作者所有,并根据 :component_file:`LICENSE 文件 ` 中描述的 BSD 许可证进行许可。 + +* :component_file:`UBSAN 运行时库 ` 版权归 2016 Linaro Limited 和 Jiří Zárevúcky 所有,并根据二条款 BSD 许可证进行许可。 + +* :component:`HTTP 解析器 ` 基于 NGINX 中的 src/http/ngx_http_parse.c 文件,版权归 Igor Sysoev 所有。任何对源代码的额外修改经过与 NGINX、Joyent 公司及其他 Node 贡献者相同条款的许可。详情请参阅 :component_file:`LICENSE 文件 `。 + +* `SEGGER SystemView`_ 目标端库,版权归 1995-2021 赛格集团所有,并根据一条款 BSD 许可证进行许可。 + +* `protobuf-c`_ 是 C 语言的 Protocol Buffers 实现,版权归 2008-2022 Dave Benson 及 protobuf-c 作者所有。详情请参阅 :component_file:`LICENSE 文件 `。 + +* `CMock`_ C 语言模拟和存根生成器,版权归 2007-14 Mike Karlesky、 Mark VanderVoord 和 Greg Williams 所有,并根据 :component_file:`LICENSE 文件 ` 中描述的 MIT 许可证进行许可。 + +* `Unity`_ 简单单元测试库,版权归 2007-23 Mike Karlesky、Mark VanderVoord 和 Greg Williams 所有,并根据 :component_file:`LICENSE 文件 ` 中描述的 MIT 许可证进行许可。 + +文档 +---- + +* `ESP-IDF 编程指南`_ 的 HTML 版本使用 Sphinx 主题 `sphinx_idf_theme`_,版权归 2013-2020 Dave Snider、Read the Docs 平台及其贡献者,以及乐鑫科技所有,基于 `sphinx_rtd_theme`_。`sphinx_idf_theme`_ 和 `sphinx_rtd_theme`_ 均根据 MIT 许可证进行许可。 + +ROM 源代码版权 +============== + +乐鑫芯片中的 Mask ROM 包含以下部分第三方软件编译的二进制文件: + +* :component:`Newlib `,如 :component_file:`COPYING.NEWLIB ` 所述,由 BSD 许可证进行许可,版权归各方所有。 + +* Xtensa libhal,版权归 Tensilica 公司所有,并根据下述 MIT 许可证进行许可。 + +* TinyBasic_ Plus,版权归 Mike Field 和 Scott Lawrence 所有,并根据下述 MIT 许可证进行许可。 + +* miniz_,由 Rich Geldreich 提供,已置于公共领域。 + +* TJpgDec_ 版权归 2011 ChaN 所有,见下文许可证。 + +* 以下是 Zephyr RTOS USB 协议栈的部分内容: + * `DesignWare USB 设备驱动程序`_ 版权归 2016 英特尔公司所有,并根据 Apache License 2.0 进行许可。 + * `Generic USB 设备驱动程序`_ 版权归 2006 Bertrik Sikken (bertrik@sikken.nl)、2016 英特尔公司所有,并根据三条款 BSD 许可证进行许可。 + * `USB 描述符功能`_ 版权归 2017 PHYTEC Messtechnik GmbH 和 2017-2018 英特尔公司所有,并根据 Apache License 2.0 进行许可。 + * `USB DFU 类驱动程序`_ 版权归 2015-2016 英特尔公司和 2017 PHYTEC Messtechnik GmbH 所有,并根据三条款 BSD 许可证进行许可。 + * `USB CDC ACM 类驱动程序`_ 版权归 2015-2016 英特尔公司所有,并根据 Apache License 2.0 进行许可。 + +.. only:: CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB + + * `Mbed TLS`_ 库,版权归 2006-2018 安谋控股公司所有,并根据 Apache License 2.0 进行许可。 + +Xtensa libhal MIT 许可证 +======================== + +版权归 2003、2006、2010 Tensilica 公司所有。 + +特此免费授予获得本软件及相关文档(以下简称“本软件”)副本的任何人、授予其他被提供软件的人,无限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、出版、发布、再许可和/或销售本软件的副本,但需符合以下条件: + +上述版权声明和本许可声明应包含在本软件的所有副本或重要内容中。 + +本软件按“原样”提供,不提供任何明示或暗示的担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对因本软件、使用本软件、或其他与本软件相关的交易而产生的任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中。 + +TinyBasic Plus MIT 许可证 +========================= + +版权归 2012-2013 Mike Field 和 Scott Lawrence 所有。 + +特此免费授予获得本软件及相关文档(以下简称“本软件”)副本的任何人、授予其他被提供软件的人,无限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、出版、发布、再许可和/或销售本软件的副本,但需符合以下条件: + +上述版权声明和本许可声明应包含在本软件的所有副本或重要内容中。 + +本软件按“原样”提供,不提供任何明示或暗示的担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对因本软件、使用本软件、或其他与本软件相关的交易而产生的任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中。 + +TJpgDec 许可证 +============== + +TJpgDec - Tiny JPEG 解压器 R0.01 (C) 2011 ChaN,是一个用于小型嵌入式系统的通用 JPEG 解压缩模块。这是一个开源的自由软件,可用于教育、研究和商业开发,许可证政策如下: + +版权归 2011 ChaN 所有。 + +* TJpgDec 模块是一个自由软件,不提供任何担保。 +* 没有使用限制,可以在个人、非营利或商业产品中使用、修改和重新发布本软件,但须自行承担责任。 +* 重新发布源代码时必须保留上述版权声明。 + + +.. _Newlib: https://sourceware.org/newlib/ +.. _FreeRTOS: https://freertos.org/ +.. _esptool.py: https://github.com/espressif/esptool +.. _LWIP: https://savannah.nongnu.org/projects/lwip/ +.. _TinyBasic: https://github.com/BleuLlama/TinyBasicPlus +.. _miniz: https://code.google.com/archive/p/miniz/ +.. _wpa_supplicant: https://w1.fi/wpa_supplicant/ +.. _FreeBSD net80211: https://github.com/freebsd/freebsd-src/tree/master/sys/net80211 +.. _TJpgDec: http://elm-chan.org/fsw/tjpgd/00index.html +.. _argtable3: https://github.com/argtable/argtable3 +.. _linenoise: https://github.com/antirez/linenoise +.. _fatfs: http://elm-chan.org/fsw/ff/00index_e.html +.. _cJSON: https://github.com/DaveGamble/cJSON +.. _micro-ecc: https://github.com/kmackay/micro-ecc +.. _OpenBSD SD/MMC 驱动程序: https://github.com/openbsd/src/blob/f303646/sys/dev/sdmmc/sdmmc.c +.. _Mbed TLS: https://github.com/Mbed-TLS/mbedtls +.. _spiffs: https://github.com/pellepl/spiffs +.. _CMock: https://github.com/ThrowTheSwitch/CMock +.. _protobuf-c: https://github.com/protobuf-c/protobuf-c +.. _Unity: https://github.com/ThrowTheSwitch/Unity +.. _asio: https://github.com/chriskohlhoff/asio +.. _mqtt: https://github.com/espressif/esp-mqtt +.. _zephyr: https://github.com/zephyrproject-rtos/zephyr +.. _mynewt-nimble: https://github.com/apache/mynewt-nimble +.. _ESP-IDF 编程指南: https://docs.espressif.com/projects/esp-idf/zh_CN/latest/ +.. _sphinx_idf_theme: https://github.com/espressif/sphinx_idf_theme +.. _sphinx_rtd_theme: https://github.com/readthedocs/sphinx_rtd_theme +.. _SEGGER SystemView: https://www.segger.com/downloads/systemview/ +.. _DesignWare USB 设备驱动程序: https://github.com/zephyrproject-rtos/zephyr/blob/v1.12-branch/drivers/usb/device/usb_dc_dw.c +.. _Generic USB 设备驱动程序: https://github.com/zephyrproject-rtos/zephyr/blob/v1.12-branch/subsys/usb/usb_device.c +.. _USB 描述符功能: https://github.com/zephyrproject-rtos/zephyr/blob/v1.12-branch/subsys/usb/usb_descriptor.c +.. _USB DFU 类驱动程序: https://github.com/zephyrproject-rtos/zephyr/blob/v1.12-branch/subsys/usb/class/usb_dfu.c +.. _USB CDC ACM 类驱动程序: https://github.com/zephyrproject-rtos/zephyr/blob/v1.12-branch/subsys/usb/class/cdc_acm.c diff --git a/docs/zh_CN/api-guides/external-ram.rst b/docs/zh_CN/api-guides/external-ram.rst index cfd851fdd40..51c39a4fb00 100644 --- a/docs/zh_CN/api-guides/external-ram.rst +++ b/docs/zh_CN/api-guides/external-ram.rst @@ -55,8 +55,7 @@ ESP-IDF 完全支持将片外 RAM 集成到你的应用程序中。在启动并 * :ref:`external_ram_config_malloc` (default) * :ref:`external_ram_config_bss` :esp32: * :ref:`external_ram_config_noinit` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_instructions` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_rodata` + :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_xip` .. _external_ram_config_memory_map: @@ -82,7 +81,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 在 :ref:`CONFIG_SPIRAM_USE` 中选择 ``Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)`` 选项。 -启用上述选项后,片外 RAM 被映射到数据虚拟地址空间,并将这个区域添加到携带 ``MALLOC_CAP_SPIRAM`` 标志的 :doc:`堆内存分配器 ` 。 +启用上述选项后,片外 RAM 被映射到数据虚拟地址空间,并将这个区域添加到携带 ``MALLOC_CAP_SPIRAM`` 标志的 :doc:`堆内存分配器 `。 程序如果想从片外存储器分配存储空间,则需要调用 ``heap_caps_malloc(size, MALLOC_CAP_SPIRAM)``,之后可以调用 ``free()`` 函数释放这部分存储空间。 @@ -114,7 +113,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项。 -启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp, wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 +启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp、wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 通过将宏 ``EXT_RAM_BSS_ATTR`` 应用于任何静态声明(未初始化为非零值),可以将附加数据从内部 BSS 段移到片外 RAM。 @@ -137,35 +136,54 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 .. only:: SOC_SPIRAM_XIP_SUPPORTED - .. _external_ram_config_instructions: + .. only:: esp32s2 or esp32s3 - 将 flash 中的指令移至 PSRAM - ----------------------------------- + 将 flash 中的指令移至 PSRAM + ----------------------------------- - 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 + 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 - 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后: + 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后: - - flash ``.text`` 部分中的指令将在系统启动时移至 PSRAM。 + - flash ``.text`` 部分中的指令将在系统启动时移至 PSRAM。 - - 上述指令对应的虚拟内存范围也将重新映射至 PSRAM。 + - 上述指令对应的虚拟内存范围也将重新映射至 PSRAM。 - 如果同时启用 :ref:`CONFIG_SPIRAM_RODATA`,SPI1 flash 操作期间不会禁用 cache。ISR、ISR 回调和相关数据无需放在内部 RAM 中,因此可以优化内部 RAM 的使用。 + 将 flash 中的只读数据移至 PSRAM + --------------------------------------- - .. _external_ram_config_rodata: + 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 - 将 flash 中的只读数据移至 PSRAM - --------------------------------------- + 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后: - 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 + - flash ``.rodata`` 部分中的指令将在系统启动时移至 PSRAM。 - 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后: + - 上述只读数据对应的虚拟内存范围也将重新映射至 PSRAM。 - - flash ``.rodata`` 部分中的指令将在系统启动时移至 PSRAM。 + .. _external_ram_config_xip: - - 上述只读数据对应的虚拟内存范围也将重新映射至 PSRAM。 + 在 PSRAM 中直接执行代码 + ------------------------------------ + + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,可同时指定 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 选项。 + + 在 PSRAM 中直接执行代码的好处包括: + + - PSRAM 访问速度快于 flash,因此性能更好。 + + - 在进行 SPI1 flash 操作期间,cache 仍然保持启用状态,这样可以优化代码执行性能。由于无需把中断服务程序 (ISR)、ISR 回调和在此期间可能被访问的数据放置在片上 RAM 中,片上 RAM 可用于其他用途,从而提高了使用效率。这个特性适用于需要处理大量数据的高吞吐量外设应用,能显著提高 SPI1 flash 操作期间的性能。 + + .. only:: esp32p4 + + .. _external_ram_config_xip: + + 在 PSRAM 中直接执行代码 + ------------------------------------ + + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后能在 PSRAM 中直接执行代码。通常放置在 flash 中的段,如 ``.text`` 部分的数据(用于指令)和 ``.rodata`` 部分的数据(用于只读数据),将被加载到 PSRAM 中。 + + 启用此选项后,SPI1 flash 操作期间 cache 保持启用状态,因此需要执行的代码在此期间不必放置在内部 RAM 中。由于 ESP32-P4 flash 和 PSRAM 使用两个独立的 SPI 总线,将 flash 内容移动到 PSRAM 实际上增加了 PSRAM MSPI 总线的负载,因此访问速度相对较慢。应用程序在运行过程中对 PSRAM 的使用会直接影响整体性能。因此,建议先进行性能分析以确定启用此选项是否会显著影响应用程序性能。 - 如果同时启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS`,SPI1 flash 操作期间不会禁用 cache。ISR、ISR 回调和相关数据无需放在内部 RAM 中,因此可以优化内部 RAM 的使用。 片外 RAM 使用限制 =================== @@ -192,7 +210,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 初始化失败 -===================== +==================== 默认情况下,片外 RAM 初始化失败将终止 ESP-IDF 启动。如果想禁用此功能,可启用 :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` 配置选项。 @@ -206,7 +224,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 加密 ========== - 可以为存储在外部 RAM 中的数据启用自动加密功能。启用该功能后,通过缓存读写的任何数据将被外部存储器加密硬件自动加密/解密。 + 可以为存储在外部 RAM 中的数据启用自动加密功能。启用该功能后,通过缓存读写的任何数据将被外部存储器加密硬件自动加密、解密。 只要启用了 flash 加密功能,就会启用这个功能。关于如何启用 flash 加密以及其工作原理,请参考 :doc:`/security/flash-encryption`。 diff --git a/docs/zh_CN/api-guides/flash_psram_config.rst b/docs/zh_CN/api-guides/flash_psram_config.rst index a3aa3dd2883..f7432c30e4e 100644 --- a/docs/zh_CN/api-guides/flash_psram_config.rst +++ b/docs/zh_CN/api-guides/flash_psram_config.rst @@ -257,7 +257,7 @@ F4R4 硬件 .. code-block:: python - python3 ./espefuse.py -p /dev/ --do-not-confirm burn_efuse FLASH_TYPE 1 + idf.py -p PORT efuse-burn --do-not-confirm FLASH_TYPE 1 .. note:: diff --git a/docs/zh_CN/api-guides/jtag-debugging/configure-other-jtag.rst b/docs/zh_CN/api-guides/jtag-debugging/configure-other-jtag.rst index 7280aa23742..d176f3d6930 100644 --- a/docs/zh_CN/api-guides/jtag-debugging/configure-other-jtag.rst +++ b/docs/zh_CN/api-guides/jtag-debugging/configure-other-jtag.rst @@ -12,7 +12,7 @@ 配置 eFuse ^^^^^^^^^^^^^^^^ - {IDF_TARGET_NAME} JTAG 接口默认连接至 :doc:`内置 USB_SERIAL_JTAG 外设 `。要使用外部 JTAG 适配器,需将 JTAG 接口切换至 GPIO 管脚。你可以使用 ``espefuse.py`` 工具来烧录 eFuse,以完成接口转换。 + {IDF_TARGET_NAME} JTAG 接口默认连接至 :doc:`内置 USB_SERIAL_JTAG 外设 `。要使用外部 JTAG 适配器,需将 JTAG 接口切换至 GPIO 管脚。你可以使用 ``idf.py`` 工具来烧录 eFuse,以完成接口转换。 .. only:: esp32c3 diff --git a/docs/zh_CN/api-guides/lwip.rst b/docs/zh_CN/api-guides/lwip.rst index b94f36748c4..34e8b485fe2 100644 --- a/docs/zh_CN/api-guides/lwip.rst +++ b/docs/zh_CN/api-guides/lwip.rst @@ -459,6 +459,10 @@ NAPT 和端口转发 如 :ref:`lwip-dns-limitation` 所述,ESP-IDF 中的 lwIP 扩展功能仍然受到全局 DNS 限制的影响。为了在应用程序代码中解决这一限制,可以使用 ``FALLBACK_DNS_SERVER_ADDRESS()`` 宏定义所有接口能够访问的全局 DNS 备用服务器,或者单独维护每个接口的 DNS 服务器,并在默认接口更改时重新配置。 +通过网络数据库 API 返回的 IP 地址数量受限:``getaddrinfo()`` 和 ``gethostbyname()`` 受到宏 ``DNS_MAX_HOST_IP`` 的限制,宏的默认值为 1。 + +在调用 ``getaddrinfo()`` 函数时,不会返回规范名称。因此,第一个返回的 ``addrinfo`` 结构中的 ``ai_canonname`` 字段仅包含 ``nodename`` 参数或相同内容的字符串。 + 在 UDP 套接字上重复调用 ``send()`` 或 ``sendto()`` 最终可能会导致错误。此时 ``errno`` 报错为 ``ENOMEM``,错误原因是底层网络接口驱动程序中的 buffer 大小有限。当所有驱动程序的传输 buffer 已满时,UDP 传输事务失败。如果应用程序需要发送大量 UDP 数据报,且不希望发送方丢弃数据报,建议检查错误代码,采用短延迟的重传机制。 .. only:: esp32 diff --git a/docs/zh_CN/api-guides/performance/size.rst b/docs/zh_CN/api-guides/performance/size.rst index a8731a84556..1a9545e7dcf 100644 --- a/docs/zh_CN/api-guides/performance/size.rst +++ b/docs/zh_CN/api-guides/performance/size.rst @@ -3,8 +3,6 @@ :link_to_translation:`en:[English]` -{IDF_TARGET_REDUCED_BY_IRAM: default="DRAM", esp32="IRAM 和/或 DRAM(取决于大小)"} - ESP-IDF 构建系统会编译项目和 ESP-IDF 中所有源文件,但只有程序实际引用的函数和变量才会链接到最终的二进制文件中。在某些情况下,需要减小固件二进制文件的总大小,例如,为使固件适配 flash 分区大小。 要减小固件二进制文件总大小,首先要找到导致其大小增加的原因。 @@ -14,312 +12,12 @@ ESP-IDF 构建系统会编译项目和 ESP-IDF 中所有源文件,但只有程 测量静态数据大小 --------------------------- -为了优化固件二进制文件大小和内存使用,需要测量项目中静态分配的 RAM (``data``, ``bss``),代码 (``text``) 和只读数据 (``rodata``)。 - -使用 :ref:`idf.py` 的子命令 ``size``, ``size-components`` 和 ``size-files`` 可以输出项目使用内存概况: - -.. note:: - - 添加 ``-DOUTPUT_FORMAT=csv`` 或 ``-DOUTPUT_FORMAT=json``,即可用 CSV 或 JSON 格式输出文件。 - -数据大小概况 ``idf.py size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. only:: esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used static DRAM: 10608 bytes ( 170128 remain, 5.9% used) - .data size: 8464 bytes - .bss size: 2144 bytes - Used static IRAM: 48834 bytes ( 82238 remain, 37.3% used) - .text size: 47807 bytes - .vectors size: 1027 bytes - Used Flash size : 117391 bytes - .text: 80103 bytes - .rodata: 37032 bytes - Total image size: 174689 bytes (.bin may be padded larger) - - -.. only:: not esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used stat D/IRAM: 53743 bytes ( 122385 remain, 30.5% used) - .data size: 6504 bytes - .bss size: 1984 bytes - .text size: 44228 bytes - .vectors size: 1027 bytes - Used Flash size : 118879 bytes - .text: 83467 bytes - .rodata: 35156 bytes - Total image size: 170638 bytes (.bin may be padded larger) - -该输出结果细分了固件二进制文件中所有静态内存区域的大小: - -.. only:: esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used static DRAM: 10608 bytes ( 170128 remain, 5.9% used) - .data size: 8464 bytes - .bss size: 2144 bytes - Used static IRAM: 48834 bytes ( 82238 remain, 37.3% used) - .text size: 47807 bytes - .vectors size: 1027 bytes - Used Flash size : 117391 bytes - .text: 80103 bytes - .rodata: 37032 bytes - Total image size: 174689 bytes (.bin may be padded larger) - - - ``Used static DRAM``:编译时分配的 DRAM 大小。 ``remain`` 表示在运行时可用作堆内存的 DRAM 余量。请注意,由于元数据开销、实现限制和启动时的堆分配,实际的 DRAM 堆会更小。 - - - ``.data size``:编译时为 ``.data`` (即所有初始化值为非零值的静态变量)分配的 DRAM 大小。 ``.data`` 还在二进制映像中占用空间来存储非零初始化值。 - - ``.bss size``:编译时为 ``.bss`` (即所有初始化值为零的静态变量)分配的 DRAM 大小。``.bss`` 不会在 flash 中占用额外空间。 - - - ``Used static IRAM``:编译时分配的 IRAM 大小。 ``remain`` 表示在运行时可用作堆内存的 IRAM 余量。请注意,由于元数据开销、实现限制和启动时的堆分配,实际的 IRAM 堆会更小。 - - - ``.text size``:用于 ``.text`` 的 IRAM 大小(即所有从 :ref:`IRAM ` 执行的代码)。由于代码最初存储在 ``.text`` 中,在启动时才会复制到 IRAM,因此 ``.text`` 在二进制映像中也会占用空间。 - - - ``Used Flash size``:使用的 flash 大小(不包括 DRAM 和 IRAM 的使用量)。 - - - ``.text``:用于 ``.text`` (即通过 flash 缓存执行的所有代码,请参阅 :ref:`IROM `)的 flash 大小。 - - ``.rodata``:用于 ``.rodata`` (即通过 flash 缓存加载的只读数据,参阅 :ref:`DROM `)的 flash 大小。 - - - ``Total image size`` 是二进制文件的预估总大小。 - -.. only:: not esp32 - - .. code-block:: bash - - $ idf.py size - [...] - Total sizes: - Used stat D/IRAM: 53743 bytes ( 122385 remain, 30.5% used) - .data size: 6504 bytes - .bss size: 1984 bytes - .text size: 44228 bytes - .vectors size: 1027 bytes - Used Flash size : 118879 bytes - .text: 83467 bytes - .rodata: 35156 bytes - Total image size: 170638 bytes (.bin may be padded larger) - - - ``Used stat D/IRAM``:编译时使用的 D/IRAM 大小。``remain`` 表示在运行时可用作堆内存的 D/IRAM 余量。请注意,由于元数据开销、实现限制和启动时的堆分配,实际的 DRAM 堆会更小。 - - - ``.data size``:编译时为 ``.data`` (即所有初始化值为非零值的静态变量)分配的 D/IRAM 大小。 ``.data`` 还在二进制映像中占用空间来存储非零初始化值。 - - ``.bss size``:编译时为 ``.bss`` (即所有初始化值为零的静态变量)分配的 D/IRAM 大小。``.bss`` 不会在 flash 中占用额外空间。 - - ``.text size``:用于 ``.text`` 的 D/IRAM 大小(即所有从内部 RAM 执行的代码)。由于代码最初存储在 ``.text`` 中,在启动时才会复制到 D/IRAM,因此 ``.text`` 在二进制映像中也会占用空间。 - - - ``Used Flash size``:使用的 flash 总大小(不包括 D/IRAM 的使用量)。 - - - ``.text``:用于 ``.text`` (即通过 flash 缓存执行的所有代码,请参阅 :ref:`IROM `)的 flash 大小。 - - ``.rodata``:用于 ``.rodata`` (即通过 flash 缓存加载的只读数据,参阅 :ref:`DROM `)的 flash 大小。 - - - ``Total image size`` is the estimated total size of the binary file. - - -组件使用概况 ``idf.py size-components`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -``idf.py size`` 的输出结果不够详细,无法找出导致二进制文件过大的主要原因。要进行更详细的分析,请使用 ``idf.py size-components`` 。 - -.. code-block:: bash - - $ idf.py size-components - [...] - Total sizes: - DRAM .data size: 14956 bytes - DRAM .bss size: 15808 bytes - Used static DRAM: 30764 bytes ( 149972 available, 17.0% used) - Used static IRAM: 83918 bytes ( 47154 available, 64.0% used) - Flash code: 559943 bytes - Flash rodata: 176736 bytes - Total image size:~ 835553 bytes (.bin may be padded larger) - Per-archive contributions to ELF file: - Archive File DRAM .data & .bss & other IRAM D/IRAM Flash code & rodata Total - libnet80211.a 1267 6044 0 5490 0 107445 18484 138730 - liblwip.a 21 3838 0 0 0 97465 16116 117440 - libmbedtls.a 60 524 0 0 0 27655 69907 98146 - libmbedcrypto.a 64 81 0 30 0 76645 11661 88481 - libpp.a 2427 1292 0 20851 0 37208 4708 66486 - libc.a 4 0 0 0 0 57056 6455 63515 - libphy.a 1439 715 0 7798 0 33074 0 43026 - libwpa_supplicant.a 12 848 0 0 0 35505 1446 37811 - libfreertos.a 3104 740 0 15711 0 367 4228 24150 - libnvs_flash.a 0 24 0 0 0 14347 2924 17295 - libspi_flash.a 1562 294 0 8851 0 1840 1913 14460 - libesp_system.a 245 206 0 3078 0 5990 3817 13336 - libesp-tls.a 0 4 0 0 0 5637 3524 9165 - [... removed some lines here ...] - libesp_rom.a 0 0 0 112 0 0 0 112 - libcxx.a 0 0 0 0 0 47 0 47 - (exe) 0 0 0 3 0 3 12 18 - libesp_pm.a 0 0 0 0 0 8 0 8 - libesp_eth.a 0 0 0 0 0 0 0 0 - libmesh.a 0 0 0 0 0 0 0 0 - -``idf.py size-components`` 输出的前几行与 ``idf.py size`` 相同,此外还会输出 ``Per-archive contributions to ELF file`` 表格,显示每个静态库对最终二进制文件大小的贡献程度。 - -通常,每个组件都会构建一个静态库归档文件,尽管部分是由特定组件包含的二进制库,例如, ``esp_wifi`` 组件包含了 ``libnet80211.a``。此外,这里还列出了一些工具链库,例如 ``libc.a`` 和 ``libgcc.a``,用于提供 C/C++ 标准库和工具链内置功能。 - -对于只有一个 ``main`` 组件的简单项目,可在 ``libmain.a`` 目录下找到所有项目代码。若项目包含其特有组件(参阅 :doc:`/api-guides/build-system`),则每个组件将单独在一行中显示。 - -该表格按静态库归档文件对最终二进制文件大小的贡献程度降序排序。 - -各列含义如下: - -.. list:: - - - ``DRAM .data & .bss & other`` - ``.data`` 和 ``.bss`` 分别与上方显示的总数相同。两者都是静态变量,且都会减少运行时的可用 RAM,但 ``.bss`` 不会增加二进制文件大小。 ``other`` 列指任何会增加 RAM 大小的自定义数据段,该值通常为 0。 - :esp32: - ``IRAM`` - 该列与上方显示的总数相同,表示链接到从 IRAM 执行的代码,这些代码占用二进制文件空间,并且会减少执行 ``HEAP_CAP_32BIT`` 时可动态分配的 IRAM。 - :esp32: - ``D/IRAM`` - 显示了 IRAM 占用的空间。D/IRAM 占用的空间会减少运行时可用作堆内存的 DRAM 空间。 - :not esp32: - ``IRAM`` - 与上方显示的总数相同,表示链接到从 IRAM 执行的代码,这些代码占用二进制文件空间,并且会减少运行时可用作堆内存的 DRAM 空间。 - - ``Flash code & rodata`` - 这些值与上方显示总数相同,指通过 flash 缓存访问的 IROM 和 DROM 空间,对二进制文件大小的贡献。 - -源文件使用概况 ``idf.py size-files`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -要了解更多详情,请运行 ``idf.py size-files``,获取每个目标文件对最终二进制文件大小的贡献概况。每个目标文件对应一个单独的源文件。 - -.. code-block:: bash - - $ idf.py size-files - [...] - Total sizes: - DRAM .data size: 14956 bytes - DRAM .bss size: 15808 bytes - Used static DRAM: 30764 bytes ( 149972 available, 17.0% used) - Used static IRAM: 83918 bytes ( 47154 available, 64.0% used) - Flash code: 559943 bytes - Flash rodata: 176736 bytes - Total image size:~ 835553 bytes (.bin may be padded larger) - Per-file contributions to ELF file: - Object File DRAM .data & .bss & other IRAM D/IRAM Flash code & rodata Total - x509_crt_bundle.S.o 0 0 0 0 0 0 64212 64212 - wl_cnx.o 2 3183 0 221 0 13119 3286 19811 - phy_chip_v7.o 721 614 0 1642 0 16820 0 19797 - ieee80211_ioctl.o 740 96 0 437 0 15325 2627 19225 - pp.o 1142 45 0 8871 0 5030 537 15625 - ieee80211_output.o 2 20 0 2118 0 11617 914 14671 - ieee80211_sta.o 1 41 0 1498 0 10858 2218 14616 - lib_a-vfprintf.o 0 0 0 0 0 13829 752 14581 - lib_a-svfprintf.o 0 0 0 0 0 13251 752 14003 - ssl_tls.c.o 60 0 0 0 0 12769 463 13292 - sockets.c.o 0 648 0 0 0 11096 1030 12774 - nd6.c.o 8 932 0 0 0 11515 314 12769 - phy_chip_v7_cal.o 477 53 0 3499 0 8561 0 12590 - pm.o 32 364 0 2673 0 7788 782 11639 - ieee80211_scan.o 18 288 0 0 0 8889 1921 11116 - lib_a-svfiprintf.o 0 0 0 0 0 9654 1206 10860 - lib_a-vfiprintf.o 0 0 0 0 0 10069 734 10803 - ieee80211_ht.o 0 4 0 1186 0 8628 898 10716 - phy_chip_v7_ana.o 241 48 0 2657 0 7677 0 10623 - bignum.c.o 0 4 0 0 0 9652 752 10408 - tcp_in.c.o 0 52 0 0 0 8750 1282 10084 - trc.o 664 88 0 1726 0 6245 1108 9831 - tasks.c.o 8 704 0 7594 0 0 1475 9781 - ecp_curves.c.o 28 0 0 0 0 7384 2325 9737 - ecp.c.o 0 64 0 0 0 8864 286 9214 - ieee80211_hostap.o 1 41 0 0 0 8578 585 9205 - wdev.o 121 125 0 4499 0 3684 580 9009 - tcp_out.c.o 0 0 0 0 0 5686 2161 7847 - tcp.c.o 2 26 0 0 0 6161 1617 7806 - ieee80211_input.o 0 0 0 0 0 6797 973 7770 - wpa.c.o 0 656 0 0 0 6828 55 7539 - [... additional lines removed ...] - -文件总大小概况下方会显示 ``Per-file contributions to ELF file`` 表格。 - -该表格的列与上文运行 ``idy.py size-components`` 显示的列相同,但该表格的粒度更细,展示了每个目标文件对二进制文件大小的贡献。 - -例如,文件 ``x509_crt_bundle.S.o`` 对总固件大小贡献了 64,212 字节,全都存储在 flash 中的 ``.rodata`` 区域。由此可以推知,该应用程序正在使用 :doc:`/api-reference/protocols/esp_crt_bundle` 功能。如果不使用该功能,固件大小至少可以减少 64,212 字节。 - -某些目标文件从二进制库中链接至此,因此无法找到对应源文件。要确定一个源文件属于哪个组件,通常可以在 ESP-IDF 源代码树中搜索,或者在 :ref:`linker-map-file` 中查找完整路径。 - -比较两个二进制文件 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -如果某些改动影响了二进制文件大小,可以使用 ESP-IDF 工具来详细分析文件大小的确切差异。 - -该操作不是通过运行 ``idf.py`` 进行的,而是需要直接运行 Python 工具 `esp_idf_size `_ 。 - -执行该操作,首先需要在构建目录中找到链接器映射文件 ``PROJECTNAME.map``。 ``esp_idf_size`` 工具会基于链接器映射文件的输出结果分析文件大小差异。 - -要与另一个二进制文件进行比较,还需要保存该文件对应的 ``.map`` 文件,该文件位于构建目录中。 - -例如,要比较两个构建文件,其中一个使用默认的 :ref:`CONFIG_COMPILER_OPTIMIZATION` ``Debug (-Og)`` 配置,而另一个使用 ``Optimize for size (-Os)`` 配置: - -.. code-block:: bash - - $ python -m esp_idf_size --diff build_Og/https_request.map build_Os/https_request.map - MAP file: build_Os/https_request.map - MAP file: build_Og/https_request.map - Difference is counted as - , i.e. a positive number means that is larger. - Total sizes of : Difference - DRAM .data size: 14516 bytes 14956 -440 - DRAM .bss size: 15792 bytes 15808 -16 - Used static DRAM: 30308 bytes ( 150428 available, 16.8% used) 30764 -456 ( +456 available, +0 total) - Used static IRAM: 78498 bytes ( 52574 available, 59.9% used) 83918 -5420 ( +5420 available, +0 total) - Flash code: 509183 bytes 559943 -50760 - Flash rodata: 170592 bytes 176736 -6144 - Total image size:~ 772789 bytes (.bin may be padded larger) 835553 -62764 - -从 ``Difference`` 列可以看出,改变该设置导致整个二进制文件减小了 60 KB 以上,并且可用的 RAM 增加了 5 KB 以上。 - -还可以使用 ``diff`` 模式来输出表格,显示组件级(静态库)的差异: - -.. note:: - - 运行 ``esp_idf_size`` 时可以使用 ``--format`` 选项输出 JSON 或 CSV 格式的结果。 - -.. code-block:: bash - - python -m esp_idf_size --archives --diff build_Og/https_request.map build_Oshttps_request.map - -同样适用于比较单个源文件级的差异: - -.. code-block:: bash - - python -m esp_idf_size --files --diff build_Og/https_request.map build_Oshttps_request.map - -了解将输出写入文件等其他选项,可以输入 ``--help`` 查看完整列表。 - -.. _idf-size-linker-failed: - -链接器失败时显示文件大小 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -如果被分配的静态内存大小超越上限,链接器会失败并显示错误信息,例如 ``DRAM segment data does not fit`` 和 ``region `iram0_0_seg' overflowed by 44 bytes`` 等。 - -在这些情况下, ``idf.py size`` 也无法成功执行。然而,通过手动运行 ``esp_idf_size``,可以查看 **部分静态内存使用情况** 。内存使用情况将不包含无法链接的变量,因此仍然会显示有部分可用空间。 - -映射文件参数为构建目录下的 ``.map`` 文件。 - -.. code-block:: bash - - python -m esp_idf_size build/project_name.map - -还可以查看类似于 ``size-components`` 或 ``size-files`` 输出的内容: - -.. code-block:: bash - - python -m esp_idf_size --archives build/project_name.map - python -m esp_idf_size --files build/project_name.map +为了优化固件二进制文件大小和内存使用,需要测量项目中静态分配的 RAM (``data``, ``bss``),代码 (``text``) 和只读数据 (``rodata``)。:ref:`idf.py` 工具的子命令 ``size``、``size-components`` 和 ``size-files`` 可分别用于检查不同级别静态分配的 RAM 使用情况。详情请参阅 :doc:`/api-guides/tools/idf-size` 工具。 .. _linker-map-file: 链接器映射文件 -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------- .. note:: diff --git a/docs/zh_CN/api-guides/tools/idf-size.rst b/docs/zh_CN/api-guides/tools/idf-size.rst new file mode 100644 index 00000000000..7c33412d2c8 --- /dev/null +++ b/docs/zh_CN/api-guides/tools/idf-size.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-guides/tools/idf-size.rst diff --git a/docs/zh_CN/api-guides/tools/index.rst b/docs/zh_CN/api-guides/tools/index.rst index 6702bcd48f1..44916de2606 100644 --- a/docs/zh_CN/api-guides/tools/index.rst +++ b/docs/zh_CN/api-guides/tools/index.rst @@ -11,4 +11,5 @@ idf-component-manager idf-clang-tidy idf-tools + idf-size :esp32 or esp32c3: qemu diff --git a/docs/zh_CN/api-reference/network/esp_netif.rst b/docs/zh_CN/api-reference/network/esp_netif.rst index 0b6a9a34fd0..a57d4b5496d 100644 --- a/docs/zh_CN/api-reference/network/esp_netif.rst +++ b/docs/zh_CN/api-reference/network/esp_netif.rst @@ -152,7 +152,7 @@ E) ESP-NETIF L2 TAP 接口 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ESP-NETIF L2 TAP 接口是 ESP-IDF 访问用户应用程序中的数据链路层(OSI/ISO 中的 L2)以进行帧接收和传输的机制。在嵌入式开发中,它通常用于实现非 IP 相关协议,如 PTP 和 Wake on LAN 等。请注意,目前 ESP-NETIF L2 TAP 接口仅支持以太网 (IEEE 802.3)。 -使用 VFS 的文件描述符访问 ESP-NETIF L2 TAP 接口,VFS 文件描述符会提供类似文件的接口(调用 ``open()``、 ``read()``、 ``write()`` 等函数访问),详情请参阅 :doc:`/api-reference/storage/vfs`。 +使用 VFS 的文件描述符访问 ESP-NETIF L2 TAP 接口,VFS 文件描述符会提供类似文件的接口(调用 ``open()``、``read()``、``write()`` 等函数访问),详情请参阅 :doc:`/api-reference/storage/vfs`。 ESP-NETIF 只提供一个 L2 TAP 接口设备(路径名),但由于 ESP-NETIF L2 TAP 接口也可作为第二层基础设施的通用入口点,因此可以同时打开多个不同配置的文件描述符。特定文件描述符的具体配置很关键,它可以配置为仅允许访问由 ``if_key`` (如 `ETH_DEF`)标识的特定网络接口,并根据帧类型(如 IEEE 802.3 中的以太网类型)过滤特定帧。由于 ESP-NETIF L2 TAP 需要与 IP 堆栈同时存在,因此不应将 IP 相关流量(IP、ARP 等)直接传递给用户应用程序,此时则需要通过配置过滤特定帧实现这一点。在未过滤的情况下,即使该选项仍可配置,也不建议在标准用例中使用。过滤的另一优势在于,过滤后,用户应用程序只能访问它感兴趣的帧类型,其余的流量会传递到其他 L2 TAP 文件描述符或 IP 堆栈。 @@ -188,7 +188,7 @@ ESP-NETIF L2 TAP 可以使用 ``O_NONBLOCK`` 文件状态标志打开,确保 ` 当前不支持识别 VLAN 标记帧。如果用户需要处理 VLAN 标记帧,应将过滤器设置为等于 VLAN 标记(即 0x8100 或 0x88A8),并在用户应用程序中处理 VLAN 标记帧。 .. note:: - 当用户应用程序不需要使用 IP 栈时, ``L2TAP_S_DEVICE_DRV_HNDL`` 将非常适用,也无需初始化 ESP-NETIF。但在此情况下,网络接口无法通过 ``if_key`` 来识别,需要通过 IO 驱动程序句柄直接标识网络接口。 + 当用户应用程序不需要使用 IP 栈时,``L2TAP_S_DEVICE_DRV_HNDL`` 将非常适用,也无需初始化 ESP-NETIF。但在此情况下,网络接口无法通过 ``if_key`` 来识别,需要通过 IO 驱动程序句柄直接标识网络接口。 | 成功时,``ioctl()`` 返回 0。出错时,返回 -1,并设置 ``errno`` 以指示错误类型: | * EBADF - 文件描述符无效。 @@ -373,6 +373,58 @@ ESP-NETIF 编程手册 * 在 ``AP+STA`` 模式下使用 Wi-Fi 时,须创建以上全部接口。 +IP 事件:发送或接收数据包 +--------------------------------- + +每次发送或接收 IP 数据包会触发 ``IP_EVENT_TX_RX`` 事件,该事件提供有关数据包传输或接收、数据长度和 ``esp_netif`` 句柄的信息。 + +启用事件 +------------------ + +**编译时间:** + +编译时使用 kconfig 中的 :ref:`CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC` 标志,可完全禁用启动事件。 + +**运行时间:** + +在运行时,你可以使用函数 :cpp:func:`esp_netif_tx_rx_event_enable()` 和 :cpp:func:`esp_netif_tx_rx_event_disable()` 来启用或禁用此事件。 + +事件注册 +------------------ + +要处理此事件,请使用以下语法注册一个处理程序: + +.. code-block:: c + + static void + tx_rx_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) + { + ip_event_tx_rx_t *event = (ip_event_tx_rx_t *)event_data; + + if (event->dir == ESP_NETIF_TX) { + ESP_LOGI(TAG, "Got TX event: Interface \"%s\" data len: %d", esp_netif_get_desc(event->esp_netif), event->len); + } else if (event->dir == ESP_NETIF_RX) { + ESP_LOGI(TAG, "Got RX event: Interface \"%s\" data len: %d", esp_netif_get_desc(event->esp_netif), event->len); + } else { + ESP_LOGI(TAG, "Got Unknown event: Interface \"%s\"", esp_netif_get_desc(event->esp_netif)); + } + } + + esp_event_handler_register(IP_EVENT, IP_EVENT_TX_RX, &tx_rx_event_handler, NULL); + +``tx_rx_event_handler`` 为处理该事件的函数的名称。 + +事件数据结构 +---------------- + +事件数据结构,:cpp:class:`ip_event_tx_rx_t` 包含以下字段: + +- :cpp:member:`ip_event_tx_rx_t::dir`: 表示数据包是传输 ``ESP_NETIF_TX`` 还是接收 ``ESP_NETIF_RX``。 +- :cpp:member:`ip_event_tx_rx_t::len`: 数据帧的长度。 +- :cpp:member:`ip_event_tx_rx_t::esp_netif`: 数据包发送或接收的网络接口。 + + API 参考 ------------- diff --git a/docs/zh_CN/api-reference/peripherals/clk_tree.rst b/docs/zh_CN/api-reference/peripherals/clk_tree.rst index 46ab9c20c81..18705f495d4 100644 --- a/docs/zh_CN/api-reference/peripherals/clk_tree.rst +++ b/docs/zh_CN/api-reference/peripherals/clk_tree.rst @@ -7,7 +7,7 @@ {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} diff --git a/docs/zh_CN/api-reference/peripherals/ecdsa.rst b/docs/zh_CN/api-reference/peripherals/ecdsa.rst index 829c89230f0..c9e444bd24d 100644 --- a/docs/zh_CN/api-reference/peripherals/ecdsa.rst +++ b/docs/zh_CN/api-reference/peripherals/ecdsa.rst @@ -22,11 +22,11 @@ ECDSA 外设可以为 TLS 双向身份验证等用例建立 **安全设备身份 在 {IDF_TARGET_NAME} 上,ECDSA 模块使用烧录到 eFuse 块中的密钥。密码模块外的任何资源都不可访问此密钥(默认模式),从而避免密钥泄露。 -ECDSA 密钥可以通过 ``espefuse.py`` 脚本在外部编程: +ECDSA 密钥可以通过 ``idf.py`` 脚本在外部编程。以下是关于编程 ECDSA 密钥的示例: .. code:: bash - espefuse.py burn_key ECDSA_KEY + idf.py efuse-burn-key ECDSA_KEY .. only:: SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK diff --git a/docs/zh_CN/api-reference/peripherals/hmac.rst b/docs/zh_CN/api-reference/peripherals/hmac.rst index 7f30144f217..dfa39222ace 100644 --- a/docs/zh_CN/api-reference/peripherals/hmac.rst +++ b/docs/zh_CN/api-reference/peripherals/hmac.rst @@ -98,7 +98,7 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接 **第一步:设置** 1. 生成一个 256 位的 HMAC 密钥,用于重新启用 JTAG。 -2. 将步骤 1 获得的密钥写入 eFuse 块,且 eFuse 块的密钥功能参数应为 HMAC_DOWN_ALL (5) 或 HMAC_DOWN_JTAG (6)。为此,可以使用固件中的 ``esp_efuse_write_key()`` 函数,或使用主机上的 ``espefuse.py`` 完成操作。 +2. 将步骤 1 获得的密钥写入 eFuse 块,且 eFuse 块的密钥功能参数应为 HMAC_DOWN_ALL (5) 或 HMAC_DOWN_JTAG (6)。为此,可以使用固件中的 ``esp_efuse_write_key()`` 函数,或使用主机上的 ``idf.py efuse-burn-key`` 完成操作。 3. 使用 ``esp_efuse_set_read_protect()`` 将 eFuse 密钥块配置为读保护,防止软件读取写入到 eFuse 密钥块中的 HMAC 密钥值。 4. 在烧录到 {IDF_TARGET_NAME} 上时,将特定的位或位组设置为 ``soft JTAG disable``。这样可以永久禁用 JTAG 接口,除非软件提供正确的密钥值进行验证。 diff --git a/docs/zh_CN/api-reference/peripherals/lcd/spi_lcd.rst b/docs/zh_CN/api-reference/peripherals/lcd/spi_lcd.rst index 5a3a760f48a..1460cd39fc1 100644 --- a/docs/zh_CN/api-reference/peripherals/lcd/spi_lcd.rst +++ b/docs/zh_CN/api-reference/peripherals/lcd/spi_lcd.rst @@ -25,6 +25,8 @@ SPI 接口的 LCD - :cpp:member:`esp_lcd_panel_io_spi_config_t::spi_mode` 设置 SPI 模式。LCD 驱动程序使用此模式与 LCD 通信。有关 SPI 模式的详细信息,请参阅 :doc:`SPI 主机 API 文档 `。 - :cpp:member:`esp_lcd_panel_io_spi_config_t::lcd_cmd_bits` 和 :cpp:member:`esp_lcd_panel_io_spi_config_t::lcd_param_bits` 分别设置 LCD 控制器芯片可识别的命令及参数的位宽。不同芯片对位宽要求不同,请提前参阅 LCD 规格书。 - :cpp:member:`esp_lcd_panel_io_spi_config_t::trans_queue_depth` 设置 SPI 传输队列的深度。该值越大,可以排队的传输越多,但消耗的内存也越多。 + - :cpp:member:`esp_lcd_panel_io_spi_config_t::cs_ena_pretrans` 设置 SPI 在传输之前应激活 CS 信号线的 SPI 位周期数 (0-16)。 + - :cpp:member:`esp_lcd_panel_io_spi_config_t::cs_ena_posttrans` 设置 SPI 在传输之后保持激活 CS 信号线的 SPI 位周期数 (0-16)。 .. code-block:: c diff --git a/docs/zh_CN/api-reference/peripherals/ledc.rst b/docs/zh_CN/api-reference/peripherals/ledc.rst index 71dbdd9d365..5baae074a73 100644 --- a/docs/zh_CN/api-reference/peripherals/ledc.rst +++ b/docs/zh_CN/api-reference/peripherals/ledc.rst @@ -166,7 +166,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实 - ~ 17.5 MHz - 支持动态调频 (DFS) 功能,支持 Light-sleep 模式 * - XTAL_CLK - - 48/40 MHz + - 48 MHz - 支持动态调频 (DFS) 功能 .. only:: esp32c6 diff --git a/docs/zh_CN/api-reference/peripherals/pcnt.rst b/docs/zh_CN/api-reference/peripherals/pcnt.rst index 3de14ab0d9e..175010e4047 100644 --- a/docs/zh_CN/api-reference/peripherals/pcnt.rst +++ b/docs/zh_CN/api-reference/peripherals/pcnt.rst @@ -25,6 +25,7 @@ PCNT 的功能从以下几个方面进行说明: - :ref:`pcnt-resource-allocation` - 说明如何通过配置分配 PCNT 单元和通道,以及在相应操作完成之后,如何回收单元和通道。 - :ref:`pcnt-setup-channel-actions` - 说明如何设置通道针对不同信号沿和电平进行操作。 - :ref:`pcnt-watch-points` - 说明如何配置观察点,即当计数达到某个数值时,命令 PCNT 单元触发某个事件。 + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :ref:`pcnt-step-notify` - 说明如何配置观察步进,即当计数增量达到某个数值时,命令 PCNT 单元触发某个事件。 - :ref:`pcnt-register-event-callbacks` - 说明如何将您的代码挂载到观察点事件的回调函数上。 - :ref:`pcnt-set-glitch-filter` - 说明如何使能毛刺滤波器并设置其时序参数。 :SOC_PCNT_SUPPORT_CLEAR_SIGNAL: - :ref:`pcnt-set-clear-signal` - 说明如何使能外部清零信号并设置其参数。 @@ -47,9 +48,13 @@ PCNT 单元和通道分别用 :cpp:type:`pcnt_unit_handle_t` 与 :cpp:type:`pcnt 安装 PCNT 单元时,需要先完成配置 :cpp:type:`pcnt_unit_config_t`: -- :cpp:member:`pcnt_unit_config_t::low_limit` 与 :cpp:member:`pcnt_unit_config_t::high_limit` 用于指定内部计数器的最小值和最大值。当计数器超过任一限值时,计数器将归零。 -- :cpp:member:`pcnt_unit_config_t::accum_count` 用于设置是否需要软件在硬件计数值溢出的时候进行累加保存,这有助于“拓宽”计数器的实际位宽。默认情况下,计数器的位宽最高只有 16 比特。请参考 :ref:`pcnt-compensate-overflow-loss` 了解如何利用此功能来补偿硬件计数器的溢出损失。 -- :cpp:member:`pcnt_unit_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。 +.. list:: + + - :cpp:member:`pcnt_unit_config_t::low_limit` 与 :cpp:member:`pcnt_unit_config_t::high_limit` 用于指定内部计数器的最小值和最大值。当计数器超过任一限值时,计数器将归零。 + - :cpp:member:`pcnt_unit_config_t::accum_count` 用于设置是否需要软件在硬件计数值溢出的时候进行累加保存,这有助于“拓宽”计数器的实际位宽。默认情况下,计数器的位宽最高只有 16 比特。请参考 :ref:`pcnt-compensate-overflow-loss` 了解如何利用此功能来补偿硬件计数器的溢出损失。 + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_up` 配置是否使能观察正方向步进。 + :SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_down` 配置是否使能观察负方向步进。 + - :cpp:member:`pcnt_unit_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。 .. note:: @@ -141,7 +146,36 @@ PCNT 单元可被设置为观察几个特定的数值,这些被观察的数值 由于硬件上的限制,在添加一个新的观察点后,你需要调用 :cpp:func:`pcnt_unit_clear_count` 函数来使之生效。 -.. _pcnt-register-event-callbacks: +.. only:: SOC_PCNT_SUPPORT_STEP_NOTIFY + + .. _pcnt-step-notify: + + PCNT 观察步进 + ^^^^^^^^^^^^^^^^ + + PCNT 单元可被设置为观察一个特定的数值增量(可以是正方向或负方向),这个观察数值增量的功能被称为 **观察步进**。启用观察步进需要使能 :cpp:member:`pcnt_unit_config_t::en_step_notify_up` 或 :cpp:member:`pcnt_unit_config_t::en_step_notify_down` 选项。 步进间隔不能超过 :cpp:type:`pcnt_unit_config_t` 设置的范围,最小值和最大值分别为 :cpp:member:`pcnt_unit_config_t::low_limit` 和 :cpp:member:`pcnt_unit_config_t::high_limit`。当计数器增量到达步进间隔时,会触发一个观察事件,如果在 :cpp:func:`pcnt_unit_register_event_callbacks` 注册过事件回调函数,该事件就会通过中断发送通知。关于如何注册事件回调函数,请参考 :ref:`pcnt-register-event-callbacks`。 + + 观察步进分别可以通过 :cpp:func:`pcnt_unit_add_watch_step` 和 :cpp:func:`pcnt_unit_remove_watch_step` 进行添加和删除。不能同时添加多个观察步进,否则将返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。 + + 建议通过 :cpp:func:`pcnt_unit_remove_watch_step` 删除未使用的观察步进来回收资源。 + + .. note:: + + 当观察步进和观察点同时被触发时,回调函数只会被调用一次。 + 步进间隔必须是 :cpp:member:`pcnt_unit_config_t::low_limit` 或 :cpp:member:`pcnt_unit_config_t::high_limit` 的因数。 + + .. code:: c + + // add positive direction step notify with 100 step intervals + ESP_ERROR_CHECK(pcnt_unit_add_watch_step(pcnt_unit, 100)); + + .. _pcnt-register-event-callbacks: + +.. only:: not SOC_PCNT_SUPPORT_STEP_NOTIFY + + .. _pcnt-register-event-callbacks: + + 注册事件回调函数 ^^^^^^^^^^^^^^^^^^^^ @@ -152,9 +186,9 @@ PCNT 单元可被设置为观察几个特定的数值,这些被观察的数值 可通过 ``user_ctx`` 将函数上下文保存到 :cpp:func:`pcnt_unit_register_event_callbacks` 中,这些数据会直接传递给回调函数。 -驱动程序会将特定事件的数据写入回调函数中,例如,观察点事件数据被声明为 :cpp:type:`pcnt_watch_event_data_t`: +驱动程序会将特定事件的数据写入回调函数中,例如,观察点事件或观察步进事件数据被声明为 :cpp:type:`pcnt_watch_event_data_t`: -- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` 用于保存触发该事件的观察点数值。 +- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` 用于保存触发事件时计数器的数值。 - :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` 用于保存上一次 PCNT 单元的过零模式,:cpp:type:`pcnt_unit_zero_cross_mode_t` 中列出了所有可能的过零模式。通常,不同的过零模式意味着不同的 **计数方向** 和 **计数步长**。 注册回调函数会导致中断服务延迟安装,因此回调函数只能在 PCNT 单元被 :cpp:func:`pcnt_unit_enable` 使能之前调用。否则,回调函数会返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。 @@ -278,8 +312,11 @@ PCNT 单元的滤波器可滤除信号中的短时毛刺,:cpp:type:`pcnt_glitc PCNT 内部的硬件计数器会在计数达到高/低门限的时候自动清零。如果你想补偿该计数值的溢出损失,以期进一步拓宽计数器的实际位宽,你可以: +.. list:: + 1. 在安装 PCNT 计数单元的时候使能 :cpp:member:`pcnt_unit_config_t::accum_count` 选项。 - 2. 将高/低计数门限设置为 :ref:`pcnt-watch-points`. + :SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. 将高/低计数门限设置为 :ref:`pcnt-watch-points` 或添加观察步进 :ref:`pcnt-step-notify` + :not SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. 将高/低计数门限设置为 :ref:`pcnt-watch-points`。 3. 现在,:cpp:func:`pcnt_unit_get_count` 函数返回的计数值就会包含硬件计数器当前的计数值,累加上计数器溢出造成的损失。 .. note:: diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index 75662fa9910..eb3b3dab14a 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -19,7 +19,7 @@ SPI1 flash 并发约束 .. only:: SOC_SPIRAM_XIP_SUPPORTED - 在 {IDF_TARGET_NAME} 上,启用配置选项 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` (默认禁用)和 :ref:`CONFIG_SPIRAM_RODATA` (默认禁用)后将允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`xip_from_psram`,查看详细信息。 + 在 {IDF_TARGET_NAME} 上,启用配置选项 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` (默认禁用)后将允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`xip_from_psram`,查看详细信息。 禁用该选项时,在读取/写入/擦除 flash 期间,必须禁用 cache。使用驱动访问 SPI1 的相关约束参见 :ref:`impact_disabled_cache`。这些约束会带来更多的 IRAM/DRAM 消耗。 @@ -40,7 +40,7 @@ SPI1 flash 并发约束 .. note:: - 同时启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 选项后,不会禁用 cache。 + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,不会禁用 cache。 .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc b/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc index 0ab88d805b2..ec11ccda61b 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc @@ -3,10 +3,8 @@ 在 PSRAM 中执行代码 ---------------------- -启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 +启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,flash 中 ``.text`` 部分的数据(用于指令)和 flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 -启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 - -相应的虚拟内存地址将被重新映射到 PSRAM。 +相应的虚拟内存地址将被映射到 PSRAM。 如果同时启用以上两个选项,则在 SPI1 flash 操作期间 cache 不会被禁用,无需确保 ISR、ISR 回调及相关数据放置在内部 RAM 中。 diff --git a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst new file mode 100644 index 00000000000..e8bab47973b --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst @@ -0,0 +1 @@ +.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_ext_hub.rst diff --git a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst index c6318a690a1..09d410debfb 100644 --- a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst +++ b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst @@ -1,56 +1 @@ -USB 主机维护者注意事项(简介) -============================== - -:link_to_translation:`en:[English]` - -本文档包含有关 USB 主机协议栈实现细节的信息,面向 USB 主机协议栈的维护者和第三方贡献者。USB 主机协议栈的用户请参考 :doc:`../usb_host`。 - -.. warning:: - - USB 主机协议栈的实现细节属于私有 API,因此,除 USB 主机库外的所有层均不遵循 :ref:`ESP-IDF 版本简介 `,即允许进行重大更改。 - -.. figure:: ../../../../_static/usb_host/stack-overview.png - :align: center - :alt: 主机协议栈层次结构图 - -本文档分为以下几个部分: - -.. toctree:: - :maxdepth: 1 - - usb_host_notes_design - usb_host_notes_arch - usb_host_notes_dwc_otg - usb_host_notes_usbh - usb_host_notes_enum - -待写章节: - -- USB 主机维护者注意事项(HAL 和 LL) -- USB 主机维护者注意事项(HCD) -- USB 主机维护者注意事项(Hub) -- USB 主机维护者注意事项(USB Host Library) - -.. -------------------------------------------------- Introduction ----------------------------------------------------- - -简介 ----- - -ESP-IDF USB 主机协议栈允许 {IDF_TARGET_NAME} 作为 USB 主机运行,此时,{IDF_TARGET_NAME} 能够与各种 USB 设备通信。然而,大多数 USB 主机协议栈实现都不运行在嵌入式硬件上(即在电脑和手机端运行),因此,相对来说具有更多的资源(即,具有更高内存和 CPU 速度)。 - -ESP-IDF USB 主机协议栈(以下简称为主机协议栈)的实现考虑到了 {IDF_TARGET_NAME} 的嵌入式特性,这体现在主机协议栈设计的各个方面。 - -特性和局限性 -^^^^^^^^^^^^ - -**主机协议栈目前支持以下显著特性:** - -- 支持 FS(全速)和 LS(低速)设备 -- 支持所有传输类型(控制传输、批量传输、同步传输和中断传输) -- 自动枚举已连接设备 -- 允许多个类驱动程序(即 USB 主机库的客户端)同时运行并共享同一设备(即组合设备) - -**主机协议栈目前存在以下显著局限:** - -- 不支持 HS(高速)设备 -- 不支持集线器(当前仅支持单个设备) +.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_index.rst diff --git a/docs/zh_CN/api-reference/protocols/esp_tls.rst b/docs/zh_CN/api-reference/protocols/esp_tls.rst index 534c8b79241..9b77551370e 100644 --- a/docs/zh_CN/api-reference/protocols/esp_tls.rst +++ b/docs/zh_CN/api-reference/protocols/esp_tls.rst @@ -208,8 +208,10 @@ MbedTLS 与 WolfSSL 对比 在 ESP-TLS 中使用 ECDSA 外设 ----------------------------- - ESP-TLS 支持在 {IDF_TARGET_NAME} 中使用 ECDSA 外设。使用 ECDSA 外设时,ESP-TLS 必须与 MbedTLS 一起作为底层 SSL/TLS 协议栈,并且 ECDSA 的私钥应存储在 eFuse 中。请参考 `espefuse.py `__ 文档,了解如何在 eFuse 中烧写 ECDSA 密钥。 + ESP-TLS 支持在 {IDF_TARGET_NAME} 中使用 ECDSA 外设。使用 ECDSA 外设时,ESP-TLS 必须与 MbedTLS 一起作为底层 SSL/TLS 协议栈,并且 ECDSA 的私钥应存储在 eFuse 中。请参考 :doc:`ECDSA 指南 <../peripherals/ecdsa>`,了解如何在 eFuse 中烧写 ECDSA 密钥。 + 在 ESP-TLS 中启用 ECDSA 外设前,请将 :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` 设置为 `true`,并将 :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` 设置为存储了 ECDSA 密钥的 eFuse 块 ID。 + 这样就可以使用 ECDSA 外设进行私钥操作。由于客户私钥已经存储在 eFuse 中,因此无需将其传递给 :cpp:type:`esp_tls_cfg_t`。 .. code-block:: c diff --git a/docs/zh_CN/api-reference/storage/index.rst b/docs/zh_CN/api-reference/storage/index.rst index 38b614ae4ac..04077378ac7 100644 --- a/docs/zh_CN/api-reference/storage/index.rst +++ b/docs/zh_CN/api-reference/storage/index.rst @@ -33,5 +33,6 @@ spiffs vfs wear-levelling + storage-security.rst 此部分 API 代码示例存放在 ESP-IDF 示例项目的 :example:`storage` 目录下。 diff --git a/docs/zh_CN/api-reference/storage/nvs_encryption.rst b/docs/zh_CN/api-reference/storage/nvs_encryption.rst index a5fb7008451..41997211cd1 100644 --- a/docs/zh_CN/api-reference/storage/nvs_encryption.rst +++ b/docs/zh_CN/api-reference/storage/nvs_encryption.rst @@ -122,7 +122,7 @@ NVS 密钥分区 .. note:: 可以使用以下命令预先在 eFuse 中设置自己的 HMAC 密钥: :: - espefuse.py -p PORT burn_key HMAC_UP + idf.py -p PORT efuse-burn-key HMAC_UP 加密读/写 -------------------- diff --git a/docs/zh_CN/api-reference/storage/storage-security.rst b/docs/zh_CN/api-reference/storage/storage-security.rst new file mode 100644 index 00000000000..2f40fa44671 --- /dev/null +++ b/docs/zh_CN/api-reference/storage/storage-security.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/storage/storage-security.rst diff --git a/docs/zh_CN/api-reference/system/efuse.rst b/docs/zh_CN/api-reference/system/efuse.rst index 7beb1e600f8..3b1e98525ba 100644 --- a/docs/zh_CN/api-reference/system/efuse.rst +++ b/docs/zh_CN/api-reference/system/efuse.rst @@ -421,7 +421,7 @@ eFuse 位序采取小字节序(参见下方示例),这说明 eFuse 位按 .. code-block:: none - $ espefuse.py dump + $ idf.py efuse-dump USER_DATA (BLOCK3 ) [3 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C BLOCK4 (BLOCK4 ) [4 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C @@ -511,7 +511,7 @@ eFuse 位序采取小字节序(参见下方示例),这说明 eFuse 位按 }, } -可以通过项目顶层目录下的 ``CMakeLists.txt`` (:example_file:`get-started/hello_world/CMakeLists.txt`) 来使用这些函数: +可以通过项目顶层目录下的 ``CMakeLists.txt`` (:example_file:`system/efuse/CMakeLists.txt`) 来使用这些函数: .. code-block:: cmake @@ -522,13 +522,13 @@ eFuse 位序采取小字节序(参见下方示例),这说明 eFuse 位按 espefuse_get_efuse(ret_data ${efuse_json} "MAC" "value") message("MAC:" ${ret_data}) -``value`` 属性的格式与 ``espefuse.py summary`` 中显示的格式相同。 +``value`` 属性的格式与 ``espefuse.py summary`` 或 ``idf.py efuse-summary`` 中显示的格式相同。 .. code-block:: none MAC:94:b9:7e:5a:6e:58 (CRC 0xe2 OK) -在示例测试 :example_file:`system/efuse/CMakeLists.txt` 中,添加了一个自定义目标 ``efuse-summary``。这样,不仅在项目构建阶段,而在任何时候都可以运行 ``idf.py efuse-summary`` 命令读取所需的 eFuse(在 ``efuse_names`` 列表中指定)。 +在示例测试 :example_file:`system/efuse/CMakeLists.txt` 中,添加了一个自定义目标 ``efuse-filter``。这样,不仅在项目构建阶段,而在任何时候都可以运行 ``idf.py efuse-filter`` 命令读取所需的 eFuse(在 ``efuse_names`` 列表中指定)。 调试 eFuse & 单元测试 ------------------------ diff --git a/docs/zh_CN/api-reference/system/inc/show-efuse-table_ESP32-C5.rst b/docs/zh_CN/api-reference/system/inc/show-efuse-table_ESP32-C5.rst index 83365425f17..1da159cd106 100644 --- a/docs/zh_CN/api-reference/system/inc/show-efuse-table_ESP32-C5.rst +++ b/docs/zh_CN/api-reference/system/inc/show-efuse-table_ESP32-C5.rst @@ -1,4 +1 @@ - -.. code-block:: none - - To be updated for C5 +.. include:: ../../../en/api-reference/system/inc/show-efuse-table_ESP32-C5.rst diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index 10a67020d52..76567ecffea 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -304,6 +304,20 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒 esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON); + .. only:: SOC_PM_SUPPORT_TOP_PD + + .. note:: + + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,为了继续使用 :cpp:func:`gpio_wakeup_enable` 用于 GPIO 唤醒, 需要先调用 :cpp:func:`rtc_gpio_init` 和 :cpp:func:`rtc_gpio_set_direction`,用于设置 RTC IO 为输入模式。 + + 或者, 可以使用直接调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 用于 GPIO 唤醒,因为此时 digital IO 的电源域已经被关闭,这个情况类似于进入 Deep-sleep。 + + .. only:: not SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,为了继续使用 :cpp:func:`gpio_wakeup_enable` 用于 GPIO 唤醒, 需要先调用 :cpp:func:`rtc_gpio_init` 和 :cpp:func:`rtc_gpio_set_direction`,用于设置 RTC IO 为输入模式。 + .. only:: not SOC_RTCIO_WAKE_SUPPORTED GPIO 唤醒 @@ -313,11 +327,13 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒 此外,可将由 VDD3P3_RTC 电源域供电的 IO 用于芯片的 Deep-sleep 唤醒。调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 函数可以配置相应的唤醒管脚和唤醒触发电平,该函数用于启用相应管脚的 Deep-sleep 唤醒功能。 - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD .. note:: - 在 Light-sleep 模式下,设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` 将使 GPIO 唤醒失效。 + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,可以使用直接调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 用于 GPIO 唤醒,因为此时 digital IO 的电源域已经被关闭,这个情况类似于进入 Deep-sleep。 UART 唤醒(仅适用于 Light-sleep 模式) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/system/ulp-lp-core.rst b/docs/zh_CN/api-reference/system/ulp-lp-core.rst index b98d804857c..5b098581483 100644 --- a/docs/zh_CN/api-reference/system/ulp-lp-core.rst +++ b/docs/zh_CN/api-reference/system/ulp-lp-core.rst @@ -101,6 +101,10 @@ ULP LP-Core 代码会与 ESP-IDF 项目共同编译,生成一个单独的二 ulp_measurement_count = 64; } +.. note:: + + LP-Core 程序全局变量存储在二进制文件的 ``.bss`` 或者 ``.data`` 部分。这些部分在加载和执行 LP-Core 二进制文件时被初始化。在首次运行 LP-Core 之前,从 HP-Core 主程序访问这些变量可能会导致未定义行为。 + 启动 ULP LP-Core 程序 -------------------------------- @@ -164,6 +168,7 @@ ULP LP-Core 支持的外设 * LP IO * LP I2C * LP UART + :SOC_LP_SPI_SUPPORTED: * LP SPI .. only:: CONFIG_ESP_ROM_HAS_LP_ROM @@ -236,6 +241,10 @@ API 参考 .. include-build-file:: inc/lp_core_i2c.inc .. include-build-file:: inc/lp_core_uart.inc +.. only:: CONFIG_SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/lp_core_spi.inc + LP 内核 API 参考 ~~~~~~~~~~~~~~~~~~~~~~ @@ -246,4 +255,8 @@ LP 内核 API 参考 .. include-build-file:: inc/ulp_lp_core_print.inc .. include-build-file:: inc/ulp_lp_core_interrupts.inc +.. only:: CONFIG_SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/ulp_lp_core_spi.inc + .. _esp-idf-monitor: https://github.com/espressif/esp-idf-monitor diff --git a/docs/zh_CN/api-reference/system/ulp-risc-v.rst b/docs/zh_CN/api-reference/system/ulp-risc-v.rst index 231ce100dff..56d42d63710 100644 --- a/docs/zh_CN/api-reference/system/ulp-risc-v.rst +++ b/docs/zh_CN/api-reference/system/ulp-risc-v.rst @@ -103,6 +103,11 @@ ULP RISC-V 协处理器代码以 C 语言(或汇编语言)编写,使用基 ulp_measurement_count = 64; } +.. note:: + + ULP RISC-V 程序全局变量存储在二进制文件的 ``.bss`` 或者 ``.data`` 部分。这些部分在加载和执行 ULP RISC-V 二进制文件时被初始化。在首次运行 ULP RISC-V 之前,从主 CPU 上的主程序访问这些变量可能会导致未定义行为。 + + 互斥 ^^^^^^^ diff --git a/docs/zh_CN/get-started/index.rst b/docs/zh_CN/get-started/index.rst index 4a6889e3ff4..8894b257500 100644 --- a/docs/zh_CN/get-started/index.rst +++ b/docs/zh_CN/get-started/index.rst @@ -130,8 +130,8 @@ .. toctree:: :maxdepth: 1 - ESP32-C3-DevKitM-1 <../hw-reference/esp32c3/user-guide-devkitm-1> - ESP32-C3-DevKitC-02 <../hw-reference/esp32c3/user-guide-devkitc-02> + ESP32-C3-DevKitC-02 + ESP32-C3-DevKitM-1 .. only:: esp32s3 diff --git a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst b/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst deleted file mode 100644 index c3388cb74b8..00000000000 --- a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst +++ /dev/null @@ -1,237 +0,0 @@ -=================== -ESP32-C3-DevKitC-02 -=================== - -:link_to_translation:`en: [English]` - -本指南将帮助你快速上手 ESP32-C3-DevKitC-02,并提供该款开发板的详细信息。 - -ESP32-C3-DevKitC-02 是一款入门级开发板,使用配置 4 MB SPI flash 的通用型模组 `ESP32-C3-WROOM-02 `_。该款开发板具备完整的 Wi-Fi 和低功耗蓝牙功能。 - -板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitC-02 - :figclass: align-center - - ESP32-C3-DevKitC-02 - -本指南包括如下内容: - -- `入门指南`_:简要介绍了 ESP32-C3-DevKitC-02 和硬件、软件设置指南。 -- `硬件参考`_:详细介绍了 ESP32-C3-DevKitC-02 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_:列出了相关文档的链接。 - - -入门指南 -======== - -本小节将简要介绍 ESP32-C3-DevKitC-02,说明如何在 ESP32-C3-DevKitC-02 上烧录固件及相关准备工作。 - - -组件介绍 --------- - -.. _user-guide-c3-devkitc-02-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitC-02 - 正面 - :figclass: align-center - - ESP32-C3-DevKitC-02 - 正面 - -以下按照逆时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - ESP32-C3-WROOM-02 - - ESP32-C3-WROOM-02 是乐鑫推出的一款通用型 Wi-Fi 和低功耗蓝牙双模模组,功能强大。该模组采用 PCB 板载天线,配置了 4 MB SPI flash。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - * - 5 V Power On LED(5 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 Flash 的 SPI 总线)均已引出至开发板的排针。请查看 :ref:`user-guide-c3-devkitc-02-v1-header-blocks` 获取更多信息。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - Micro-USB Port(Micro-USB 接口) - - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-C3 芯片的通信接口。 - * - Reset Button(Reset 键) - - 复位按键。 - * - USB-to-UART Bridge(USB 至 UART 桥接器) - - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO8 驱动。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-C3-DevKitC-02 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-C3-DevKitC-02 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 小节查看如何快速设置开发环境,将应用程序烧录至 ESP32-C3-DevKitC-02。 - - -内含组件和包装 --------------- - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-C3-DevKitC-02 开发板将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-C3-DevKitC-02 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-C3-DevKitC-02 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitC-02(点击放大) - :figclass: align-center - - ESP32-C3-DevKitC-02(点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可为 ESP32-C3-DevKitC-02 供电: - -- Micro-USB 接口供电(默认) -- 5V 和 GND 排针供电 -- 3V3 和 GND 排针供电 - -建议选择第一种供电方式:Micro-USB 接口供电。 - - -.. _user-guide-c3-devkitc-02-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-c3-devkitc-02-v1-board-front` 所示,排针的序号与 `ESP32-C3-DevKitC-02 原理图`_ (PDF) 一致。 - - -J1 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 G G 接地 -2 3V3 P 3.3 V 电源 -3 3V3 P 3.3 V 电源 -4 RST I CHIP_PU -5 G G 接地 -6 4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -7 5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -8 6 I/O/T GPIO6, FSPICLK, MTCK -9 7 I/O/T GPIO7, FSPID, MTDO -10 G G 接地 -11 8 I/O/T GPIO8 [2]_, RGB LED -12 9 I/O/T GPIO9 [2]_ -13 5V P 5 V 电源 -14 5V P 5 V 电源 -15 G G 接地 -==== ==== ========== ================================ - - -J3 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 G G 接地 -2 0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -3 1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -4 2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 3 I/O/T GPIO3, ADC1_CH3 -6 G G 接地 -7 10 I/O/T GPIO10, FSPICS0 -8 G G 接地 -9 RX I/O/T GPIO20, U0RXD -10 TX I/O/T GPIO21, U0TXD -11 G G 接地 -12 18 I/O/T GPIO18, USB_D- -13 19 I/O/T GPIO19, USB_D+ -14 G G 接地 -15 G G 接地 -==== ==== ========== ================================ - -.. [1] P:电源;I:输入;O:输出;T:可设置为高阻。 -.. [2] GPIO2、GPIO8、GPIO9 为 ESP32-C3 芯片的 Strapping 管脚。在芯片上电和系统复位过程中,Strapping 管脚根据管脚的二进制电压值控制芯片功能。Strapping 管脚的具体描述和应用,请参考 `ESP32-C3 技术规格书`_ 的 Strapping 管脚章节。 - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitC-02 管脚布局(点击放大) - :figclass: align-center - - ESP32-C3-DevKitC-02 管脚布局(点击放大) - - -硬件版本 -========== - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -======== - -* `使用 ESP32-C3 构建安全高性价比的互联设备 `_ -* `ESP32-C3 技术规格书`_ (PDF) -* `ESP32-C3-WROOM-02 规格书`_ (PDF) -* `ESP32-C3-DevKitC-02 原理图`_ (PDF) -* `ESP32-C3-DevKitC-02 PCB 布局图 `_ (PDF) -* `ESP32-C3-DevKitC-02 尺寸图 `_ (PDF) -* `ESP32-C3-DevKitC-02 尺寸图源文件 `_ (DXF) - 可使用 `Autodesk Viewer `_ 查看 - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _ESP32-C3 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf -.. _ESP32-C3-WROOM-02 规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3-wroom-02_datasheet_cn.pdf -.. _ESP32-C3-DevKitC-02 原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITC-02_V1_1_20210126A.pdf diff --git a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst b/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst deleted file mode 100644 index 76f4c71f152..00000000000 --- a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst +++ /dev/null @@ -1,240 +0,0 @@ -================== -ESP32-C3-DevKitM-1 -================== - -:link_to_translation:`en: [English]` - -本指南将帮助你快速上手 ESP32-C3-DevKitM-1,并提供该款开发板的详细信息。 - -ESP32-C3-DevKitM-1 是一款入门级开发板,使用以尺寸小而得名的 `ESP32-C3-MINI-1 `_ 模组。该款开发板具备完整的 Wi-Fi 和低功耗蓝牙功能。 - -板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitM-1 - :figclass: align-center - - ESP32-C3-DevKitM-1 - -本指南包括如下内容: - -- `入门指南`_:简要介绍了 ESP32-C3-DevKitM-1 和硬件、软件设置指南。 -- `硬件参考`_:详细介绍了 ESP32-C3-DevKitM-1 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_:列出了相关文档的链接。 - - -入门指南 -======== - -本小节将简要介绍 ESP32-C3-DevKitM-1,说明如何在 ESP32-C3-DevKitM-1 上烧录固件及相关准备工作。 - - -组件介绍 --------- - -.. _user-guide-c3-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitM-1 - 正面 - :figclass: align-center - - ESP32-C3-DevKitM-1 - 正面 - -以下按照逆时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - ESP32-C3-MINI-1 - - ESP32-C3-MINI-1 是一款通用型 Wi-Fi 和低功耗蓝牙双模模组,采用 PCB 板载天线。该款模组集成配置 4 MB 嵌入式 flash 的 `ESP32-C3FN4 `_ 芯片。由于 flash 直接封装在芯片中,ESP32-C3-MINI-1 模组具有更小的封装尺寸。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - * - 5 V Power On LED(5 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 flash 的 SPI 总线)均已引出至开发板的排针。请查看 :ref:`user-guide-c3-devkitm-1-v1-header-blocks` 获取更多信息。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - Micro-USB Port(Micro-USB 接口) - - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-C3FN4 芯片的通信接口。 - * - Reset Button(Reset 键) - - 复位按键。 - * - USB-to-UART Bridge(USB 至 UART 桥接器) - - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO8 驱动。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-C3-DevKitM-1 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-C3-DevKitM-1 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 小节查看如何快速设置开发环境,将应用程序烧录至 ESP32-C3-DevKitM-1。 - - -内含组件和包装 --------------- - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-C3-DevKitM-1 开发板将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-C3-DevKitM-1 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-C3-DevKitM-1 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitM-1 (点击放大) - :figclass: align-center - - ESP32-C3-DevKitM-1 (点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可为 ESP32-C3-DevKitM-1 供电: - -- Micro-USB 接口供电(默认) -- 5V 和 GND 排针供电 -- 3V3 和 GND 排针供电 - -建议选择第一种供电方式:Micro-USB 接口供电。 - - -.. _user-guide-c3-devkitm-1-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-c3-devkitm-1-v1-board-front` 所示,排针的序号与 `ESP32-C3-DevKitM-1 原理图`_ (PDF) 一致。 - - -J1 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 GND G 接地 -2 3V3 P 3.3 V 电源 -3 3V3 P 3.3 V 电源 -4 IO2 I/O/T GPIO2 [2]_ , ADC1_CH2, FSPIQ -5 IO3 I/O/T GPIO3, ADC1_CH3 -6 GND G 接地 -7 RST I CHIP_PU -8 GND G 接地 -9 IO0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -10 IO1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -11 IO10 I/O/T GPIO10, FSPICS0 -12 GND G 接地 -13 5V P 5 V 电源 -14 5V P 5 V 电源 -15 GND G 接地 -==== ==== ========== ================================ - - -J3 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 GND G 接地 -2 TX I/O/T GPIO21, U0TXD -3 RX I/O/T GPIO20, U0RXD -4 GND G 接地 -5 IO9 I/O/T GPIO9 [2]_ -6 IO8 I/O/T GPIO8 [2]_, RGB LED -7 GND G 接地 -8 IO7 I/O/T GPIO7, FSPID, MTDO -9 IO6 I/O/T GPIO6, FSPICLK, MTCK -10 IO5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -11 IO4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -12 GND G 接地 -13 IO18 I/O/T GPIO18, USB_D- -14 IO19 I/O/T GPIO19, USB_D+ -15 GND G 接地 -==== ==== ========== ================================ - -.. [1] P:电源;I:输入;O:输出;T:可设置为高阻。 -.. [2] GPIO2、GPIO8、GPIO9 为 ESP32-C3FN4 芯片的 Strapping 管脚。在芯片上电和系统复位过程中,Strapping 管脚根据管脚的二进制电压值控制芯片功能。Strapping 管脚的具体描述和应用,请参考 `ESP32-C3 技术规格书`_ 的 Strapping 管脚章节。 - - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitM-1 管脚布局(点击放大) - - ESP32-C3-DevKitM-1 管脚布局(点击放大) - - -硬件版本 -========== - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -======== - -* `使用 ESP32-C3 构建安全高性价比的互联设备 `_ -* `ESP32-C3 技术规格书`_ (PDF) -* `ESP32-C3-MINI-1 规格书`_ (PDF) -* `ESP32-C3-DevKitM-1 原理图`_ (PDF) -* `ESP32-C3-DevKitM-1 PCB 布局图 `_ (PDF) -* `ESP32-C3-DevKitM-1 尺寸图 `_ (PDF) -* `ESP32-C3-DevKitM-1 尺寸图源文件 `_ (DXF) - 可使用 `Autodesk Viewer `_ 查看 - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _ESP32-C3 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf -.. _ESP32-C3-MINI-1 规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_cn.pdf -.. _ESP32-C3-DevKitM-1 原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITM-1_V1_20200915A.pdf -.. _ESP32-C3-DevKitM-1 PCB 布局图: https://dl.espressif.com/dl/schematics/PCB_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 尺寸图: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 尺寸图源文件: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.dxf diff --git a/docs/zh_CN/security/esp32c6_log.inc b/docs/zh_CN/security/esp32c6_log.inc index 53eb89084ea..32a13c25c8d 100644 --- a/docs/zh_CN/security/esp32c6_log.inc +++ b/docs/zh_CN/security/esp32c6_log.inc @@ -1,13 +1,141 @@ .. first_boot_enc -TO BE UPDATED TODO IDF-5932 +.. code-block:: none + + rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT) + SPIWP:0xee + mode:DIO, clock div:2 + load:0x4086c410,len:0xd5c + load:0x4086e610,len:0x4584 + load:0x40875888,len:0x2bac + entry 0x4086c410 + I (25) boot: ESP-IDF v5.1-dev-4270-g4bff4ed6e5-dirty 2nd stage bootloader + I (25) boot: compile time Mar 27 2023 16:48:49 + I (27) boot: chip revision: v0.0 + I (30) boot.esp32c6: SPI Speed : 40MHz + I (35) boot.esp32c6: SPI Mode : DIO + I (40) boot.esp32c6: SPI Flash Size : 2MB + I (44) boot: Enabling RNG early entropy source... + W (50) bootloader_random: bootloader_random_enable() has not been implemented yet + I (58) boot: Partition Table: + I (62) boot: ## Label Usage Type ST Offset Length + I (69) boot: 0 nvs WiFi data 01 02 0000a000 00006000 + I (76) boot: 1 storage Unknown data 01 ff 00010000 00001000 + I (84) boot: 2 factory factory app 00 00 00020000 00100000 + I (91) boot: 3 nvs_key NVS keys 01 04 00120000 00001000 + I (99) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000 + I (106) boot: End of partition table + I (110) esp_image: segment 0: paddr=00020020 vaddr=42018020 size=090e8h ( 37096) map + I (126) esp_image: segment 1: paddr=00029110 vaddr=40800000 size=06f08h ( 28424) load + I (134) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=12fd8h ( 77784) map + I (151) esp_image: segment 3: paddr=00043000 vaddr=40806f08 size=03c00h ( 15360) load + I (158) boot: Loaded app from partition at offset 0x20000 + I (158) boot: Checking flash encryption... + I (160) efuse: Batch mode of writing fields is enabled + I (165) flash_encrypt: Generating new flash encryption key... + I (174) efuse: Writing EFUSE_BLK_KEY0 with purpose 4 + W (178) flash_encrypt: Not disabling UART bootloader encryption + I (184) flash_encrypt: Disable UART bootloader cache... + I (190) flash_encrypt: Disable JTAG... + I (197) efuse: BURN BLOCK4 + I (204) efuse: BURN BLOCK4 - OK (write block == read block) + I (206) efuse: BURN BLOCK0 + I (212) efuse: BURN BLOCK0 - OK (all write block bits are set) + I (216) efuse: Batch mode. Prepared fields are committed + I (222) esp_image: segment 0: paddr=00000020 vaddr=4086c410 size=00d5ch ( 3420) + I (231) esp_image: segment 1: paddr=00000d84 vaddr=4086e610 size=04584h ( 17796) + I (240) esp_image: segment 2: paddr=00005310 vaddr=40875888 size=02bach ( 11180) + I (632) flash_encrypt: bootloader encrypted successfully + I (679) flash_encrypt: partition table encrypted and loaded successfully + I (680) flash_encrypt: Encrypting partition 1 at offset 0x10000 (length 0x1000)... + I (732) flash_encrypt: Done encrypting + I (732) esp_image: segment 0: paddr=00020020 vaddr=42018020 size=090e8h ( 37096) map + I (741) esp_image: segment 1: paddr=00029110 vaddr=40800000 size=06f08h ( 28424) + I (747) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=12fd8h ( 77784) map + I (765) esp_image: segment 3: paddr=00043000 vaddr=40806f08 size=03c00h ( 15360) + I (769) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0x100000)... + I (13025) flash_encrypt: Done encrypting + I (13025) flash_encrypt: Encrypting partition 3 at offset 0x120000 (length 0x1000)... + I (13074) flash_encrypt: Done encrypting + I (13075) efuse: BURN BLOCK0 + I (13077) efuse: BURN BLOCK0 - OK (all write block bits are set) + I (13078) flash_encrypt: Flash encryption completed + I (13083) boot: Resetting with flash encryption enabled... + ------ .. already_en_enc +.. code-block:: none + + rst:0x3 (LP_SW_HPSYS),boot:0xc (SPI_FAST_FLASH_BOOT) + Saved PC:0x4001974a + SPIWP:0xee + mode:DIO, clock div:2 + load:0x4086c410,len:0xd5c + load:0x4086e610,len:0x4584 + load:0x40875888,len:0x2bac + entry 0x4086c410 + I (24) boot: ESP-IDF v5.1-dev-4270-g4bff4ed6e5-dirty 2nd stage bootloader + I (24) boot: compile time Mar 27 2023 16:48:49 + I (25) boot: chip revision: v0.0 + I (29) boot.esp32c6: SPI Speed : 40MHz + I (34) boot.esp32c6: SPI Mode : DIO + I (39) boot.esp32c6: SPI Flash Size : 2MB + I (43) boot: Enabling RNG early entropy source... + W (49) bootloader_random: bootloader_random_enable() has not been implemented yet + I (57) boot: Partition Table: + I (60) boot: ## Label Usage Type ST Offset Length + I (68) boot: 0 nvs WiFi data 01 02 0000a000 00006000 + I (75) boot: 1 storage Unknown data 01 ff 00010000 00001000 + I (83) boot: 2 factory factory app 00 00 00020000 00100000 + I (90) boot: 3 nvs_key NVS keys 01 04 00120000 00001000 + I (98) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000 + I (105) boot: End of partition table + I (109) esp_image: segment 0: paddr=00020020 vaddr=42018020 size=090e8h ( 37096) map + I (126) esp_image: segment 1: paddr=00029110 vaddr=40800000 size=06f08h ( 28424) load + I (134) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=12fd8h ( 77784) map + I (152) esp_image: segment 3: paddr=00043000 vaddr=40806f08 size=03c00h ( 15360) load + I (159) boot: Loaded app from partition at offset 0x20000 + I (159) boot: Checking flash encryption... + I (160) flash_encrypt: flash encryption is enabled (1 plaintext flashes left) + I (168) boot: Disabling RNG early entropy source... + W (173) bootloader_random: bootloader_random_enable() has not been implemented yet + I (193) cpu_start: Pro cpu up. + W (202) clk: esp_perip_clk_init() has not been implemented yet + I (208) cpu_start: Pro cpu start user code + I (209) cpu_start: cpu freq: 160000000 Hz + I (209) cpu_start: Application information: + I (211) cpu_start: Project name: flash_encryption + I (217) cpu_start: App version: v5.1-dev-4270-g4bff4ed6e5-dirty + I (224) cpu_start: Compile time: Mar 27 2023 16:49:00 + I (230) cpu_start: ELF file SHA256: df1dd35054510e16... + I (236) cpu_start: ESP-IDF: v5.1-dev-4270-g4bff4ed6e5-dirty + I (243) cpu_start: Min chip rev: v0.0 + I (248) cpu_start: Max chip rev: v0.99 + I (253) cpu_start: Chip rev: v0.0 + I (258) heap_init: Initializing. RAM available for dynamic allocation: + I (265) heap_init: At 4080B9E0 len 00070C30 (451 KiB): D/IRAM + I (271) heap_init: At 4087C610 len 00002F54 (11 KiB): STACK/DIRAM + I (278) heap_init: At 50000010 len 00003FF0 (15 KiB): RTCRAM + I (285) spi_flash: detected chip: generic + I (289) spi_flash: flash io: dio + W (293) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header. + W (306) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure) + I (314) sleep: Configure to isolate all GPIO pins in sleep state + I (320) sleep: Enable automatic switching of GPIO sleep configuration + I (327) coexist: coex firmware version: 5315623 + I (333) coexist: coexist rom version 5b8dcfa + I (338) app_start: Starting scheduler on CPU0 + I (342) main_task: Started on CPU0 + I (342) main_task: Calling app_main() + + Example to check Flash Encryption status + This is esp32c6 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.0, 2MB external flash + FLASH_CRYPT_CNT eFuse value is 1 + Flash encryption feature is enabled in DEVELOPMENT mode -TO BE UPDATED TODO IDF-5932 ------ diff --git a/docs/zh_CN/security/esp32h2_log.inc b/docs/zh_CN/security/esp32h2_log.inc index d05109d0d99..bb93f6ffc54 100644 --- a/docs/zh_CN/security/esp32h2_log.inc +++ b/docs/zh_CN/security/esp32h2_log.inc @@ -1,13 +1,138 @@ .. first_boot_enc -TO BE UPDATED +.. code-block:: none + + rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT) + SPIWP:0xee + mode:DIO, clock div:1 + load:0x4083cfd0,len:0xc0c + load:0x4083efd0,len:0x45c0 + load:0x40846248,len:0x2b48 + entry 0x4083cfd0 + I (25) boot: ESP-IDF v5.1-dev-4270-g4bff4ed6e5 2nd stage bootloader + I (25) boot: compile time Mar 27 2023 16:40:47 + I (26) boot: chip revision: v0.0 + I (29) boot.esp32h2: SPI Speed : 64MHz + I (34) boot.esp32h2: SPI Mode : DIO + I (39) boot.esp32h2: SPI Flash Size : 2MB + I (44) boot: Enabling RNG early entropy source... + W (49) bootloader_random: bootloader_random_enable() has not been implemented yet + I (57) boot: Partition Table: + I (61) boot: ## Label Usage Type ST Offset Length + I (68) boot: 0 nvs WiFi data 01 02 0000a000 00006000 + I (76) boot: 1 storage Unknown data 01 ff 00010000 00001000 + I (83) boot: 2 factory factory app 00 00 00020000 00100000 + I (90) boot: 3 nvs_key NVS keys 01 04 00120000 00001000 + I (98) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000 + I (106) boot: End of partition table + I (110) esp_image: segment 0: paddr=00020020 vaddr=42020020 size=096e0h ( 38624) map + I (128) esp_image: segment 1: paddr=00029708 vaddr=40800000 size=06910h ( 26896) load + I (135) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=1b708h (112392) map + I (163) esp_image: segment 3: paddr=0004b730 vaddr=40806910 size=02a08h ( 10760) load + I (167) esp_image: segment 4: paddr=0004e140 vaddr=40809320 size=00e5ch ( 3676) load + I (172) boot: Loaded app from partition at offset 0x20000 + I (175) boot: Checking flash encryption... + I (180) efuse: Batch mode of writing fields is enabled + I (186) flash_encrypt: Generating new flash encryption key... + I (194) efuse: Writing EFUSE_BLK_KEY0 with purpose 4 + W (198) flash_encrypt: Not disabling UART bootloader encryption + I (204) flash_encrypt: Disable JTAG... + I (212) efuse: BURN BLOCK4 + I (219) efuse: BURN BLOCK4 - OK (write block == read block) + I (221) efuse: BURN BLOCK0 + I (227) efuse: BURN BLOCK0 - OK (write block == read block) + I (231) efuse: Batch mode. Prepared fields are committed + I (236) esp_image: segment 0: paddr=00000020 vaddr=4083cfd0 size=00c0ch ( 3084) + I (245) esp_image: segment 1: paddr=00000c34 vaddr=4083efd0 size=045c0h ( 17856) + I (255) esp_image: segment 2: paddr=000051fc vaddr=40846248 size=02b48h ( 11080) + I (381) flash_encrypt: bootloader encrypted successfully + I (396) flash_encrypt: partition table encrypted and loaded successfully + I (397) flash_encrypt: Encrypting partition 1 at offset 0x10000 (length 0x1000)... + I (411) flash_encrypt: Done encrypting + I (412) esp_image: segment 0: paddr=00020020 vaddr=42020020 size=096e0h ( 38624) map + I (423) esp_image: segment 1: paddr=00029708 vaddr=40800000 size=06910h ( 26896) + I (430) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=1b708h (112392) map + I (458) esp_image: segment 3: paddr=0004b730 vaddr=40806910 size=02a08h ( 10760) + I (461) esp_image: segment 4: paddr=0004e140 vaddr=40809320 size=00e5ch ( 3676) + I (464) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0x100000)... + I (3600) flash_encrypt: Done encrypting + I (3600) flash_encrypt: Encrypting partition 3 at offset 0x120000 (length 0x1000)... + I (3612) flash_encrypt: Done encrypting + I (3613) efuse: BURN BLOCK0 + I (3616) efuse: BURN BLOCK0 - OK (all write block bits are set) + I (3617) flash_encrypt: Flash encryption completed + I (3622) boot: Resetting with flash encryption enabled... + ------ .. already_en_enc +.. code-block:: none + + rst:0x3 (LP_SW_HPSYS),boot:0xc (SPI_FAST_FLASH_BOOT) + Saved PC:0x400031a6 + SPIWP:0xee + mode:DIO, clock div:1 + load:0x4083cfd0,len:0xc0c + load:0x4083efd0,len:0x45c0 + load:0x40846248,len:0x2b48 + entry 0x4083cfd0 + I (27) boot: ESP-IDF v5.1-dev-4270-g4bff4ed6e5 2nd stage bootloader + I (28) boot: compile time Mar 27 2023 16:40:47 + I (28) boot: chip revision: v0.0 + I (32) boot.esp32h2: SPI Speed : 64MHz + I (37) boot.esp32h2: SPI Mode : DIO + I (41) boot.esp32h2: SPI Flash Size : 2MB + I (46) boot: Enabling RNG early entropy source... + W (51) bootloader_random: bootloader_random_enable() has not been implemented yet + I (60) boot: Partition Table: + I (63) boot: ## Label Usage Type ST Offset Length + I (71) boot: 0 nvs WiFi data 01 02 0000a000 00006000 + I (78) boot: 1 storage Unknown data 01 ff 00010000 00001000 + I (86) boot: 2 factory factory app 00 00 00020000 00100000 + I (93) boot: 3 nvs_key NVS keys 01 04 00120000 00001000 + I (100) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000 + I (108) boot: End of partition table + I (112) esp_image: segment 0: paddr=00020020 vaddr=42020020 size=096e0h ( 38624) map + I (131) esp_image: segment 1: paddr=00029708 vaddr=40800000 size=06910h ( 26896) load + I (140) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=1b708h (112392) map + I (171) esp_image: segment 3: paddr=0004b730 vaddr=40806910 size=02a08h ( 10760) load + I (175) esp_image: segment 4: paddr=0004e140 vaddr=40809320 size=00e5ch ( 3676) load + I (180) boot: Loaded app from partition at offset 0x20000 + I (183) boot: Checking flash encryption... + I (188) flash_encrypt: flash encryption is enabled (1 plaintext flashes left) + I (195) boot: Disabling RNG early entropy source... + W (201) bootloader_random: bootloader_random_disable() has not been implemented yet + I (221) cpu_start: Pro cpu up. + W (229) clk: esp_perip_clk_init() has not been implemented yet + I (236) cpu_start: Pro cpu start user code + I (236) cpu_start: cpu freq: 96000000 Hz + I (237) cpu_start: Application information: + I (239) cpu_start: Project name: flash_encryption + I (245) cpu_start: App version: v5.1-dev-4270-g4bff4ed6e5 + I (251) cpu_start: Compile time: Mar 27 2023 16:40:56 + I (257) cpu_start: ELF file SHA256: 42c8d825941d8050... + I (263) cpu_start: ESP-IDF: v5.1-dev-4270-g4bff4ed6e5 + I (270) cpu_start: Min chip rev: v0.0 + I (274) cpu_start: Max chip rev: v0.99 + I (279) cpu_start: Chip rev: v0.0 + I (284) heap_init: Initializing. RAM available for dynamic allocation: + I (291) heap_init: At 4080B010 len 00042370 (264 KiB): D/IRAM + I (298) heap_init: At 4084D380 len 00002B60 (10 KiB): STACK/DIRAM + I (305) spi_flash: detected chip: generic + I (309) spi_flash: flash io: dio + W (313) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header. + W (326) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure) + I (334) app_start: Starting scheduler on CPU0 + I (339) main_task: Started on CPU0 + I (339) main_task: Calling app_main() + + Example to check Flash Encryption status + This is esp32h2 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.0, 2MB external flash + FLASH_CRYPT_CNT eFuse value is 1 + Flash encryption feature is enabled in DEVELOPMENT mode -TO BE UPDATED ------ diff --git a/docs/zh_CN/security/flash-encryption.rst b/docs/zh_CN/security/flash-encryption.rst index d3be755e089..da68d9e4b51 100644 --- a/docs/zh_CN/security/flash-encryption.rst +++ b/docs/zh_CN/security/flash-encryption.rst @@ -55,7 +55,7 @@ flash 加密功能用于加密与 {IDF_TARGET_NAME} 搭载使用的片外 flash 相关 eFuses ------------------------------ -flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制。以下是这些 eFuse 列表及其描述,下表中的各 eFuse 名称也在 espefuse.py 工具中使用,为了能在 eFuse API 中使用,请在名称前加上 ``ESP_EFUSE_``,如:esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT)。 +flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制,具体 eFuse 名称及其描述请参见下表。``espefuse.py`` 工具和基于 ``idf.py`` 的 eFuse 指令也会使用下表中的 eFuse 名。为了能在 eFuse API 中使用,请在名称前加上 ``ESP_EFUSE_``,如:esp_efuse_read_field_bit (ESP_EFUSE_DISABLE_DL_ENCRYPT)。 .. Comment: As text in cells of list-table header rows does not wrap, it is necessary to make 0 header rows and apply bold typeface to the first row. Otherwise, the table goes beyond the html page limits on the right. @@ -164,7 +164,7 @@ flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制。以下是这 * 上表中列出的所有 eFuse 位都提供读/写访问控制。 * 这些位的默认值是 0。 -对上述 eFuse 位的读写访问由 ``WR_DIS`` 和 ``RD_DIS`` 寄存器中的相应字段控制。有关 {IDF_TARGET_NAME} eFuse 的详细信息,请参考 :doc:`eFuse 管理器 <../api-reference/system/efuse>`。要使用 espefuse.py 更改 eFuse 字段的保护位,请使用以下两个命令:read_protect_efuse 和 write_protect_efuse。例如 ``espefuse.py write_protect_efuse DISABLE_DL_ENCRYPT``。 +对上述 eFuse 位的读写访问由 ``WR_DIS`` 和 ``RD_DIS`` 寄存器中的相应字段控制。有关 {IDF_TARGET_NAME} eFuse 的详细信息,请参考 :doc:`eFuse 管理器 <../api-reference/system/efuse>`。要使用 ``idf.py`` 更改 eFuse 字段的保护位,请使用以下两个命令:efuse-read-protect 和 efuse-write-protect(``idf.py`` 基于 ``espefuse.py`` 命令 write_protect_efuse 和 read_protect_efuse 的别名)。例如 ``idf.py efuse-write-protect DISABLE_DL_ENCRYPT``。 .. only:: esp32c2 @@ -405,42 +405,42 @@ flash 加密设置 .. code-block:: bash - espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin + idf.py --port PORT efuse-burn-key flash_encryption my_flash_encryption_key.bin .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin KEYPURPOSE + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin KEYPURPOSE - 其中 ``BLOCK`` 是 ``BLOCK_KEY0`` 和 ``BLOCK_KEY5`` 之间的空闲密钥区。而 ``KEYPURPOSE`` 是 ``AES_256_KEY_1``、``XTS_AES_256_KEY_2`` 或 ``XTS_AES_128_KEY``。关于密钥用途,请参考 `{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_。 + 其中 ``BLOCK`` 是 ``BLOCK_KEY0`` 和 ``BLOCK_KEY5`` 之间的空闲密钥区。而 ``KEYPURPOSE`` 是 ``XTS_AES_256_KEY_1``、``XTS_AES_256_KEY_2`` 或 ``XTS_AES_128_KEY``。关于密钥用途,请参考 `{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_。 对于 AES-128(256 位密钥)- ``XTS_AES_128_KEY``: .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY - 对于 AES-256(512 位密钥)- ``XTS_AES_256_KEY_1`` 和 ``XTS_AES_256_KEY_2``。espefuse.py 支持通过虚拟密钥用途 ``XTS_AES_256_KEY`` 将这两个密钥用途和一个 512 位密钥一起烧录到两个独立的密钥块。使用此功能时,``espefuse.py`` 将把密钥的前 256 位烧录到指定的 ``BLOCK``,并把相应的区块密钥用途烧录到 ``XTS_AES_256_KEY_1``。密钥的后 256 位将被烧录到 ``BLOCK`` 后的第一个空闲密钥块,并把相应的密钥用途烧录到 ``XTS_AES_256_KEY_2``。 + 对于 AES-256(512 位密钥)- ``XTS_AES_256_KEY_1`` 和 ``XTS_AES_256_KEY_2``。``idf.py`` 支持通过虚拟密钥用途 ``XTS_AES_256_KEY`` 将这两个密钥用途和一个 512 位密钥一起烧录到两个独立的密钥块。使用此功能时,``idf.py`` 将把密钥的前 256 位烧录到指定的 ``BLOCK``,并把相应的区块密钥用途烧录到 ``XTS_AES_256_KEY_1``。密钥的后 256 位将被烧录到 ``BLOCK`` 后的第一个空闲密钥块,并把相应的密钥用途烧录到 ``XTS_AES_256_KEY_2``。 .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY 如果你想指定使用哪两个区块,则可以将密钥分成两个 256 位密钥,并分别使用 ``XTS_AES_256_KEY_1`` 和 ``XTS_AES_256_KEY_2`` 为密钥用途进行手动烧录: .. code-block:: bash split -b 32 my_flash_encryption_key.bin my_flash_encryption_key.bin. - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin.aa XTS_AES_256_KEY_1 - espefuse.py --port PORT burn_key BLOCK+1 my_flash_encryption_key.bin.ab XTS_AES_256_KEY_2 + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin.aa XTS_AES_256_KEY_1 + idf.py --port PORT efuse-burn-key BLOCK+1 my_flash_encryption_key.bin.ab XTS_AES_256_KEY_2 .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY 其中 ``BLOCK`` 是 ``BLOCK_KEY0`` 和 ``BLOCK_KEY5`` 之间的一个空闲密钥区。 @@ -450,19 +450,19 @@ flash 加密设置 .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY 对于由 128 位导出的 AES-128 密钥(SHA256(128 位))- ``XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS``。flash 加密密钥会被写入 eFuse BLOCK_KEY0 的低位,留出高 128 位以支持软件读取。如小节 ``同时烧录两个密钥`` 所示,在 espefuse 工具的特殊模式下,你可以使用任意 espefuse 命令来写入数据。 .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS + idf.py --port PORT efuse-burn-key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS 同时烧录两个密钥(安全启动和 flash 加密): .. code-block:: bash - espefuse.py --port PORT --chip esp32c2 burn_key_digest secure_boot_signing_key.pem \ + espefuse.py --port PORT --chip esp32c2 burn_key_digest secure_boot_signing_key.pem \ burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS 如果未烧录密钥并在启用 flash 加密后启动设备,{IDF_TARGET_NAME} 将生成一个软件无法访问或修改的随机密钥。 @@ -706,7 +706,7 @@ flash 加密设置 .. code-block:: bash - espefuse.py -p PORT summary + idf.py efuse-summary .. _reading-writing-content: @@ -806,11 +806,11 @@ OTA 更新 #. 在 :ref:`项目配置菜单 ` 中,禁用 :ref:`启动时使能 flash 加密 ` 选项,然后保存并退出。 #. 再次打开项目配置菜单,再次检查你是否已经禁用了该选项,如果这个选项仍被启用,引导加载程序在启动时将立即重新启用加密功能。 #. 在禁用 flash 加密后,通过运行 ``idf.py flash`` 来构建和烧录新的引导加载程序和应用程序。 -#. 使用 ``espefuse.py`` (在 ``components/esptool_py/esptool`` 中)以关闭 ``{IDF_TARGET_CRYPT_CNT}``,运行: +#. 使用 ``idf.py`` 来关闭 ``{IDF_TARGET_CRYPT_CNT}``,请运行以下命令: .. code-block:: bash - espefuse.py burn_efuse {IDF_TARGET_CRYPT_CNT} + idf.py efuse-burn {IDF_TARGET_CRYPT_CNT} 重置 {IDF_TARGET_NAME},flash 加密应处于关闭状态,引导加载程序将正常启动。 @@ -940,15 +940,15 @@ flash 加密的高级功能 .. code-block:: bash - espefuse.py --port PORT burn_efuse DISABLE_DL_DECRYPT - espefuse.py --port PORT write_protect_efuse DISABLE_DL_ENCRYPT + idf.py --port PORT efuse-burn DISABLE_DL_DECRYPT + idf.py --port PORT efuse-write-protect DISABLE_DL_ENCRYPT .. only:: not esp32 .. code-block:: bash - espefuse.py --port PORT burn_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT - espefuse.py --port PORT write_protect_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT + idf.py --port PORT efuse-burn DIS_DOWNLOAD_MANUAL_ENCRYPT + idf.py --port PORT efuse-write-protect DIS_DOWNLOAD_MANUAL_ENCRYPT .. note:: diff --git a/docs/zh_CN/security/secure-boot-v1.rst b/docs/zh_CN/security/secure-boot-v1.rst index 2b493e4d722..bff6c2691af 100644 --- a/docs/zh_CN/security/secure-boot-v1.rst +++ b/docs/zh_CN/security/secure-boot-v1.rst @@ -149,11 +149,11 @@ 1. 在 :ref:`project-configuration-menu` 中,选择 ``Bootloader Config`` > :ref:`CONFIG_SECURE_BOOT` > ``CONFIG_SECURE_BOOT_V1_ENABLED`` > :ref:`CONFIG_SECURE_BOOTLOADER_MODE` > ``Reflashable``。 -2. 如有需要,按照设备使用的编码方案设置 :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING`。编码方案将在 ``esptool.py`` 连接到芯片时显示在 ``Features`` 行中,或在 ``espefuse.py summary`` 输出中显示。 +2. 如有需要,按照设备使用的编码方案设置 :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING`。编码方案将在 ``esptool.py`` 连接到芯片时显示在 ``Features`` 行中,或在 ``idf.py efuse-summary`` 输出中显示。 3. 请按 :ref:`secure-boot-generate-key` 中的步骤生成签名密钥。生成的密钥文件路径必须在 ``Secure Boot Configuration`` 菜单中指定。 -4. 运行 ``idf.py bootloader`` 将创建一个二进制密钥文件,该文件派生自用于签名的私钥。同时将打印两组烧录步骤。第一组步骤包括一个 ``espefuse.py burn_key secure_boot_v1 path_to/secure-bootloader-key-xxx.bin`` 命令,用于将引导加载程序密钥写入 eFuse,此密钥仅可烧录一次。第二组步骤可使用预计算的摘要重新烧录引导加载程序,该摘要在构建过程中生成。 +4. 运行 ``idf.py bootloader`` 将创建一个二进制密钥文件,该文件派生自用于签名的私钥。同时将打印两组烧录步骤。第一组步骤包括一个 ``idf.py efuse-burn-key secure_boot_v1 path_to/secure-bootloader-key-xxx.bin`` 命令,用于将引导加载程序密钥写入 eFuse,此密钥仅可烧录一次。第二组步骤可使用预计算的摘要重新烧录引导加载程序,该摘要在构建过程中生成。 5. 从 :ref:`一次性烧录步骤 6 ` 继续,烧录引导加载程序并启用安全启动。请密切监视控制器日志输出,确保安全启动配置正确无误。 diff --git a/examples/get-started/blink/sdkconfig.defaults.esp32c5 b/examples/get-started/blink/sdkconfig.defaults.esp32c5 index 053efed5b7b..faee357ade7 100644 --- a/examples/get-started/blink/sdkconfig.defaults.esp32c5 +++ b/examples/get-started/blink/sdkconfig.defaults.esp32c5 @@ -1,2 +1,2 @@ -CONFIG_BLINK_GPIO=6 +CONFIG_BLINK_GPIO=27 CONFIG_BLINK_LED_STRIP=y diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 6949eafd206..1b2c076edb1 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -299,12 +299,14 @@ examples/peripherals/rmt/ir_nec_transceiver: examples/peripherals/rmt/musical_buzzer: disable: + - if: SOC_RMT_SUPPORTED != 1 - if: SOC_RMT_SUPPORT_TX_LOOP_COUNT != 1 depends_components: - esp_driver_rmt examples/peripherals/rmt/stepper_motor: disable: + - if: SOC_RMT_SUPPORTED != 1 - if: SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP != 1 depends_components: - esp_driver_rmt diff --git a/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py b/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py index 08b5e606ea6..444e1a5f97d 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py @@ -7,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py b/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py index fdd7305c6cd..81c60e6d4fd 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py @@ -8,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py b/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py index fb6a7618ab2..80c1bbf321b 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py @@ -6,6 +6,7 @@ @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py b/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py index 618c700bfda..4f44422087e 100644 --- a/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py +++ b/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py @@ -6,6 +6,7 @@ @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.generic diff --git a/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py b/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py index 03a991ff02b..c888db7af6d 100644 --- a/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py +++ b/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py @@ -8,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py b/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py index cb8f243bea9..f677a255a95 100644 --- a/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py +++ b/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s3 @pytest.mark.esp32c6 +@pytest.mark.esp32c5 @pytest.mark.esp32h2 @pytest.mark.esp32p4 @pytest.mark.generic diff --git a/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py b/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py index d53bb5d0123..11a7d01cd8e 100644 --- a/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py +++ b/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py b/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py index 2976ba136c6..23ba1a4e34c 100644 --- a/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py +++ b/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py @@ -1,12 +1,12 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py b/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py index 270d0dc4d4b..2d6bc17398d 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py @@ -4,6 +4,7 @@ from pytest_embedded import Dut +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py index f774c175627..29d17f4c81e 100644 --- a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py +++ b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded.dut import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py b/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py index 26b86312177..3f2470cea41 100644 --- a/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py +++ b/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -9,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/rmt/led_strip/pytest_led_strip.py b/examples/peripherals/rmt/led_strip/pytest_led_strip.py index afafbe5d2b2..e7f73b87a85 100644 --- a/examples/peripherals/rmt/led_strip/pytest_led_strip.py +++ b/examples/peripherals/rmt/led_strip/pytest_led_strip.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -9,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py b/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py index ce347210adb..3ba73406f00 100644 --- a/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py +++ b/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/rmt/onewire/pytest_onewire.py b/examples/peripherals/rmt/onewire/pytest_onewire.py index 2a6a7298981..3204c21ed9b 100644 --- a/examples/peripherals/rmt/onewire/pytest_onewire.py +++ b/examples/peripherals/rmt/onewire/pytest_onewire.py @@ -8,6 +8,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py b/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py index fdd2629cc54..4a730b20196 100644 --- a/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py +++ b/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py @@ -1,11 +1,11 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32s3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py index 5ffc6746148..0bda957d041 100644 --- a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py +++ b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py @@ -1,17 +1,15 @@ # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - from time import sleep import pytest -import serial import serial.tools.list_ports from pytest_embedded import Dut @pytest.mark.esp32c6 # usb_serial_jtag is very similar, test C6 is enough. @pytest.mark.usj_device -def test_usb_device_serial_example(dut: Dut) -> None: +def test_usb_device_serial_echo_example(dut: Dut) -> None: dut.expect_exact('USB_SERIAL_JTAG init done') sleep(2) diff --git a/examples/security/.build-test-rules.yml b/examples/security/.build-test-rules.yml index c540531f557..5313911a78a 100644 --- a/examples/security/.build-test-rules.yml +++ b/examples/security/.build-test-rules.yml @@ -29,3 +29,7 @@ examples/security/nvs_encryption_hmac: - nvs_sec_provider depends_filepatterns: - examples/security/nvs_encryption_hmac/**/* + +examples/security/security_features_app: + disable: + - if: IDF_TARGET not in ["esp32c3"] diff --git a/examples/security/flash_encryption/README.md b/examples/security/flash_encryption/README.md index c499289ff5f..cf4c7364369 100644 --- a/examples/security/flash_encryption/README.md +++ b/examples/security/flash_encryption/README.md @@ -3,11 +3,27 @@ # Flash Encryption -The example checks if the flash encryption feature is enabled/disabled and if enabled prints the flash encryption mode (DEVELOPMENT / RELEASE) and FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets) eFuse value. +The example demonstrates the flash encryption application by providing a code using FATFS and NVS partitions on a device with the flash encryption enabled. +As the flash encryption can be enabled either in Development or Release mode, a guidance of how to use either mode is provided. -The example also demonstrates writing and reading encrypted partitions in flash. +The example code checks if the flash encryption feature is enabled/disabled and if enabled, it prints a status information of all the eFuses related to the flash encryption mode (Development/Release) and FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets). -## How to use example +The example also demonstrates: + +1. Writing and reading encrypted partitions in the flash memory. +2. Initialization of FATFS, formatting, writing and reading file. Both encrypted as well as non-encrypted. +3. Initialization of encrypted NVS partition. Both auto-generated as well as pre-generated NVS key scenarios are presented. +4. Flashing the example in Development as well as Release mode. + +### NVS example +The example demonstrates default and custom NVS partition initialisation when the flash encryption is enabled. From the code perspective the use of NVS API is transparent regardless of the flash encryption mode. + +### FATFS example +FATFS example function finds non-encrypted partition `fat_not_encr`, erases it, creates FATFS, formats and mounts the file system. Then it creates file `/spiflash/inner.txt` using `fopen`, writes test string using `fprintf` and closes the file using `fclose`. Then it uses `fopen` and `fgets` to read the string back to verify it is correctly written. The last step of the example on unencrypted partition uses `esp_flash_read` to locate the test string in the underlying partition without involving potential cryptographic layer. The test string offset from the beginning of the partition is returned to the second part of the example. + +The second part of the example repeats FATFS related steps on the encrypted partition named `fat_encrypted`. The same sequence of steps as in the non encrypted partition means, that the file data should be present on the same offset in the partition. Therefore, direct partition reading using `esp_flash_read` uses the offset returned by the first part of example. Depending on encryption settings in the menuconfig, the test string is then read in the visible form `(SECURE_FLASH_ENC_ENABLED not set)` or in encrypted form `(SECURE_FLASH_ENC_ENABLED=y)` + +## How to use the example ### Hardware Required @@ -16,67 +32,211 @@ The example also demonstrates writing and reading encrypted partitions in flash. ``` idf.py menuconfig ``` -#### Configuration for flash encryption -* Enable the flash encryption mode (Development or Release) under Security Features. Default usage mode is Development (recommended during test and development phase). -Note: After enabling flash encryption, the bootloader size increases, which means that the offset of the partition table must be changed to 0x9000 from 0x8000 to prevent the bootloader from overlapping with the partition table. In this example, the default offset of the partition table is 0x9000. +#### Flash encryption configuration +Enable the flash encryption mode (Development or Release) under (`menuconfig -> Security Features`). Default usage mode is Development (recommended during test and development phase). + +Note: After enabling flash encryption, the bootloader size increases, which means that default offset of the partition table (`menuconfig -> Partition Table -> Offset of partition table`) has to be increased from default value of 0x8000 to prevent the bootloader from overlapping with the partition table. In this example, the offset of the partition table is incereased to 0xD000. -For better security, the NVS encryption is enabled by default when the flash encryption is enabled. If you choose to disable the NVS encryption, you can skip the NVS configuration step given below. +If you chose the Release mode, for better security, you can also disable UART ROM download mode using (`menuconfig -> Security features -> UART ROM download mode -> Permanently disabled`) +Note: This option, after first start of application, makes the device forever inaccessible using UART. Use it with care. + +This example demonstrates working with several non-default partitions, therefore a custom partition configuration file is selected. The custom file option (`menuconfig -> Partition Table -> Partition table = Custom partition table CSV`) and the name of file is set in (`menuconfig -> Partition Table -> Custom partition CSV file`). The additional entries in the custom partition table CSV file on top of default ones are described in the NVS and FATFS related subsections below. + +For better security, the NVS encryption (`menuconfig -> Component config -> NVS -> Enable NVS encryption`) is enabled by default when the flash encryption is enabled in the menuconfig. If you decide to disable the NVS encryption, you can skip the NVS configuration step given below. #### Configuration for NVS encryption -For using NVS encryption, the partition table must contain the [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition). Two partition tables containing the NVS keys partition are provided for NVS encryption under the partition table option . They can be selected with the project configuration menu (`menuconfig -> Partition Table`). This particular example uses a custom partition table as it requires a `storage` partition along with the `nvs_keys` partition. +With the NVS encryption is enabled, the partition table must contain additional [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) atop of all the NVS partitions holding data. This example uses two NVS partitions (`storage`, `nvs`) and one NVS key partition `nvs_keys`. All the partitions required are already preconfigured in `partitions_example.csv` + +The partition configuration for the NVS encryption involves generating NVS encryption keys to be stored in [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition). The NVS encryption keys can be either automatically generated by ESP32-based chip during the first run of the application, or generated and flashed to the device by the application developer. + +Automatic generation of NVS encryption keys on ESP32-based chips: +When the NVS encryption is enabled, the `nvs_flash_init` API function can internally generate the XTS encryption keys on the ESP32-based chip. The API function finds the first [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition), i.e. a partition of type `data` and subtype `nvs_keys` and when this partition is empty, the API function automatically generates NVS keys. (Consult the [`nvs_flash_init`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#_CPPv414nvs_flash_initv) API documentation in the ESP-IDF programming guide for more details). + +**Please note that `nvs_keys` partition has to be completely erased before starting the application. Otherwise the application may generate `ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that `nvs_keys` partition was not empty and contains malformed data.** + +Flash pre-generated NVS encryption keys: +This method is useful when application developer requires presence of known NVS encryption keys on a device. I.e. to allow easier analysis of the NVS partition on a host computer. +For convenience, file `sample_encryption_keys.bin` with a sample of pre-generated NVS encryption keys is provided. -The configuration for NVS encryption involves generating the XTS encryption keys in the [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) partition. It can be done with one of the following method. +#### Configuration for FATFS encryption +FATFS encryption example uses two additional partitions in the partition table. Both partitions are of type `data` and subtype `fat`. The first partition `fat_encrypted` has the encrypted flag set, the second partition `fat_not_encr` has the encryption flag off. Both partitions are defined in the partition configuration file `partitions_example.csv` -1. Generate the XTS encryption keys on the ESP chip: +### Building - When NVS encryption is enabled the `nvs_flash_init` API function can internally generate the XTS encryption keys on the ESP chip. The API function finds the first [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) i.e. a partition of type `data` and subtype `nvs_keys`. - Then the API function automatically generates and stores the - nvs keys in that partition. New keys are generated and stored only when the respective key partition is empty. (Consult the [`nvs_flash_init`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#_CPPv414nvs_flash_initv) API documentation in the ESP-IDF programming guide for more details). +``` +idf.py build +``` + +### Flashing - **Please note that `nvs_keys` partition must be completely erased before starting the application. Otherwise the application may generate `ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that `nvs_keys` partition was not empty and contains malformatted data.** +There are two flash encryption modes: Development and Release. +ESP32-based device's bootloader in the Development mode can encrypt the data to be flashed, whilst the bootloader in the Release mode cannot. Therefore the data to be flashed in Release mode has to be encrypted on a host system in advance. The workflows for both options are described below. -2. Use pre-generated XTS encryption keys: - This method will be required by the user when the `XTS encryption keys` in [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) are not generated by the application. - The pre generated `Sample XTS encryption keys` can be stored on the flash with help of the following two commands +Prerequisites: +- Flashing port of connected ESP32-based device is stored in the environment variable PORT, e.g. `export PORT=/dev/cu.usbserial-14320` +- Current directory is set to the example root, e.g. `esp-idf/examples/security/flash_encryption` + +#### Development mode + +1. Build and flash the partition table: +``` +idf.py --port $PORT partition-table partition-table-flash +``` - i) Build and flash the partition table: - ``` - idf.py partition-table partition-table-flash - ``` - ii) Store the `sample_encryption_keys.bin` in the `nvs_key`partition (on the flash) with the help of [parttool.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html#partition-tool-parttool-py): - ``` - parttool.py --port /dev/ttyUSB0 --partition-table-offset 0x9000 write_partition --partition-name="nvs_key" --input sample_encryption_keys.bin - ``` - The sample [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) partition used in this example is generated with the help of [NVS Partition Generator Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_partition_gen.html#nvs-partition-generator-utility) - . +2. If you want use pre-generated NVS encryption keys, flash the `sample_encryption_keys.bin` into the `nvs_key`partition (on the flash) with the help of [parttool.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html#partition-tool-parttool-py): +``` +parttool.py --port $PORT --partition-table-offset 0xD000 write_partition --partition-name="nvs_key" --input sample_encryption_keys.bin +``` +The sample [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) partition used in this example is generated with the help of [NVS Partition Generator Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_partition_gen.html#nvs-partition-generator-utility) -### Build and Flash -When building the project and flashing it to the board FOR THE FIRST TIME after enabling flash encryption feature in menuconfig, run following command to program the target and monitor the output: +3. When building the project and flashing it to the board FOR THE FIRST TIME (after enabling the flash encryption feature in menuconfig), run the following command to program the target and monitor the output: ``` -idf.py -p PORT flash monitor +idf.py --port $PORT flash monitor ``` (To exit the serial monitor, type ``Ctrl-]``.) -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. +4. When reprogramming the device, subsequently use the following command for encrypted write of the new non-encrypted application's binary: + +``` +idf.py --port $PORT encrypted-app-flash monitor +``` + +5. Please note that above-mentioned command programs only the 'app' partition. In order to reprogram all the partitions (bootloader, partition table and application) and let the bootloader encrypt them on the device, use: + +``` +idf.py --port $PORT encrypted-flash monitor +``` + +#### Release mode + +Full example including host generated NVS encryption keys and pre-encryption of the flash on the host is provided for ESP32 ECO3. +Steps: + +1. Generate an unique flash encryption key on a host +``` +espsecure.py generate_flash_encryption_key example_flash_encryption_key.bin +``` + +Alternatively, if you want to further develop the workflow, it might be useful to use all-zeroes "easy to restore" flash encryption key instead. However, never use this key in a production! +``` +dd if=/dev/zero of=example_flash_encryption_key.bin bs=1 count=32 +``` + +2. NVS encryption key +This workflow uses NVS encryption key provided by the example repository. It will be flashed to the `nvs_key` partition. +File name is `sample_encryption_keys.bin` + +3. Prepare data partitions to be flashed +Developers requiring pre-initialized partitions can use NVS Partition Generator Utility for NVS or FAT File System Generator for FAT filesystem. +This example assumes empty partitions. + +``` +dd if=/dev/zero bs=1 count=0x1000 of=build/storage.bin +dd if=/dev/zero bs=1 count=0x6000 of=build/nvs.bin +dd if=/dev/zero bs=1 count=0x6000 of=build/custom_nvs.bin +dd if=/dev/zero bs=1 count=0x96000 of=build/fat_encrypted.bin +dd if=/dev/zero bs=1 count=0x96000 of=build/fat_not_encr.bin +``` + +4. Encrypt flash artefacts on a host using flash encryption key. +First, figure out the offsets of particular artefacts in the flash memory, as it is one of the inputs to the encryption algorithm. +Lookup the section listing partition table in output of the command `idf.py build` i.e. +``` +Partition table binary generated. Contents: +******************************************************************************* +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0xe000,24K, +storage,data,255,0x14000,4K,encrypted +factory,app,factory,0x20000,1M, +nvs_key,data,nvs_keys,0x120000,4K,encrypted +custom_nvs,data,nvs,0x121000,24K, +fat_encrypted,data,fat,0x127000,600K,encrypted +fat_not_encr,data,fat,0x1bd000,600K, +******************************************************************************* +``` + +The offsets of the bootloader, application code and the partition table binaries can be found in `build/flash_args` +``` +0x1000 bootloader/bootloader.bin +0x20000 flash_encryption.bin +0xd000 partition_table/partition-table.bin +``` + +From the example application perspective it is necessary to encrypt every artefact except for 'nvs', 'custom_nvs' and 'fat_not_encr' partitions, as their content is expected to be plaintext. + +``` +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/bootloader_encrypted.bin --address 0x1000 build/bootloader/bootloader.bin +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/flash_encryption_encrypted.bin --address 0x20000 build/flash_encryption.bin +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/partition_table_encrypted.bin --address 0xd000 build/partition_table/partition-table.bin +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/storage_encrypted.bin --address 0x14000 build/storage.bin +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/sample_encryption_keys_encrypted.bin --address 0x120000 sample_encryption_keys.bin +espsecure.py encrypt_flash_data --keyfile example_flash_encryption_key.bin --output build/fat_encrypted_encrypted.bin --address 0x127000 build/fat_encrypted.bin +``` + +5. Merge all the flash artefacts into one file +``` +esptool.py --chip ESP32 merge_bin -o build\merged_encrypted_flash.bin --flash_mode dio --flash_size 4MB \ +0x1000 build/bootloader_encrypted.bin \ +0xd000 build/partition_table_encrypted.bin \ +0xe000 build/nvs.bin \ +0x14000 build/storage_encrypted.bin \ +0x20000 build/flash_encryption_encrypted.bin \ +0x120000 build/sample_encryption_keys_encrypted.bin \ +0x121000 build/nvs.bin \ +0x127000 build/fat_encrypted_encrypted.bin \ +0x1bd000 build/fat_not_encr.bin +``` +Ignore the warning `Warning: Image file at 0x1000 doesn't look like an image file, so not changing any flash settings.` + +Output flash binary file is `build\merged_encrypted_flash.bin` + +6. Burn the encryption key and set the efuses in ESP32-based device +This step can be performed only once. If the workflow is using non-zero flash encryption key generated in step 1, keep the encryption key file on a safe place for future application updates. + +``` +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_key flash_encryption example_flash_encryption_key.bin +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse FLASH_CRYPT_CONFIG 0xf +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse FLASH_CRYPT_CNT 127 +``` -When reprogramming the device subsequently use following command for encrypted write of new plaintext application: +7. Burn security eFuses +WARNING: This step can be performed only once! +``` +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse DISABLE_DL_ENCRYPT 0x1 +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse DISABLE_DL_DECRYPT 0x1 +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse DISABLE_DL_CACHE 0x1 +espefuse.py --chip esp32 --do-not-confirm --port $PORT burn_efuse JTAG_DISABLE 0x1 +``` +8. Flash the image to the ESP32-based device ``` -idf.py -p PORT encrypted-app-flash monitor +python -m esptool --chip esp32 --port $PORT -b 460800 write_flash --force --flash_mode dio \ +--flash_size 4MB --flash_freq 40m \ +0x0000 build\merged_encrypted_flash.bin ``` -Please note above command programs only the app partition. In order to reprogram all partitions (bootloader, partition table and application) in encrypted form use: +9. Monitor the output, then reset the device +``` +idf.py --port $PORT monitor +``` +10. You can verify the efuse settings using ``` -idf.py -p PORT encrypted-flash monitor +espefuse.py --chip esp32 --port $PORT summary ``` +For subsequent application update, only steps 4,5,8 are required. + + ## Example Output +### Development mode + When running the example without enabling flash encryption, the output would be as follows (on ESP32): ``` @@ -94,8 +254,25 @@ I (398) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f Reading with spi_flash_read: I (408) example: 0x3ffb4da0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| I (418) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +.... +I (509) example: FAT partition "fat_not_encr" is not encrypted. Size is (0x96000 bytes) +.... +I (3429) example: Read partition using esp_flash_read until test string is found +I (3649) example: 0x3ffb4f90 74 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 |the quick brown | +I (3649) example: 0x3ffb4fa0 66 6f 78 20 6a 75 6d 70 65 64 20 6f 76 65 72 20 |fox jumped over | +I (3659) example: 0x3ffb4fb0 74 68 65 20 6c 61 7a 79 20 64 6f 67 |the lazy dog| +I (3669) example: Test string was found at offset (0x7000) +.... +I (3679) example: FAT partition "fat_encrypted" is not encrypted. Size is (0x96000 bytes) +.... +I (7099) example: Read partition using esp_flash_read at expected offset (0x7000) +I (7099) example: 0x3ffb4f84 74 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 |the quick brown | +I (7099) example: 0x3ffb4f94 66 6f 78 20 6a 75 6d 70 65 64 20 6f 76 65 72 20 |fox jumped over | +I (7109) example: 0x3ffb4fa4 74 68 65 20 6c 61 7a 79 20 64 6f 67 |the lazy dog| +I (7119) example: Data matches test string ``` - +Note: Above, the partition `fat_encrypted` has flag `encrypted` set in partition table, but it's actual state +is `not encrypted` until the flash encryption is enabled in security part of menuconfig as demonstrated below. After enabling flash encryption in Development mode, the output shows the process of enabling the flash encryption: ``` @@ -132,19 +309,78 @@ I (471) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f Reading with spi_flash_read: I (491) example: 0x3ffb4b30 35 9b f2 07 b4 6d 40 89 28 b4 1e 22 98 7b 4a 36 |5....m@.(..".{J6| I (491) example: 0x3ffb4b40 ba 89 81 67 77 a3 60 5e 0a e7 51 01 b3 58 c2 f6 |...gw.`^..Q..X..| +.... +I (583) example: FAT partition "fat_not_encr" is not encrypted. Size is (0x96000 bytes) +.... +I (3863) example: Read partition using esp_flash_read until test string is found +I (4083) example: 0x3ffb4fb0 74 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 |the quick brown | +I (4083) example: 0x3ffb4fc0 66 6f 78 20 6a 75 6d 70 65 64 20 6f 76 65 72 20 |fox jumped over | +I (4093) example: 0x3ffb4fd0 74 68 65 20 6c 61 7a 79 20 64 6f 67 |the lazy dog| +I (4103) example: Test string was found at offset (0x7000) +.... +I (4113) example: FAT partition "fat_encrypted" is encrypted. Size is (0x96000 bytes) +.... +I (8033) example: Read partition using esp_flash_read at expected offset (0x7000) +I (8033) example: 0x3ffb4fa4 a7 ea d5 a7 ed cf f6 f7 4a a2 54 a0 4f 92 73 7b |........J.T.O.s{| +I (8043) example: 0x3ffb4fb4 63 eb 5d fc 14 b9 da 3b f2 be d0 94 de eb b2 dc |c.]....;........| +I (8053) example: 0x3ffb4fc4 38 aa 14 62 b7 23 61 7d b6 34 43 53 |8..b.#a}.4CS| +I (8063) example: Data does not match test string ``` - If the NVS encryption is enabled, then the output will show the status of the encrypted partition as follows ``` I (667) example_nvs: NVS partition "nvs" is encrypted. ``` + +### Release mode + +In the Release mode no in-place encryption happens after the first reset, as the bootloader assumes the flashed data is already encrypted. The log below shows the run of application after successfully finished flashing. +``` +Example to check Flash Encryption status +This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision v1.0, 4MB external flash +FLASH_CRYPT_CNT eFuse value is 127 +Flash encryption feature is enabled in RELEASE mode +Erasing partition "storage" (0x1000 bytes) +Writing data with esp_partition_write: +I (483) example: 0x3ffb5000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +I (483) example: 0x3ffb5010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +Reading with esp_partition_read: +I (493) example: 0x3ffb4fe0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +I (503) example: 0x3ffb4ff0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +Reading with esp_flash_read: +I (513) example: 0x3ffb4fe0 16 0a 38 06 c8 29 31 32 b2 1f 5a ca da e9 47 99 |..8..)12..Z...G.| +I (523) example: 0x3ffb4ff0 1d ca d6 6d 55 ad 31 57 d3 d9 df 77 43 f9 4c ca |...mU.1W...wC.L.| +.... +I (543) example_fatfs: FAT partition "fat_not_encr" is not encrypted. Size is (0x96000 bytes) +.... +I (3573) example_fatfs: Read partition using esp_flash_read until test string is found +I (3793) example_fatfs: 0x3ffb4fc0 74 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 |the quick brown | +I (3803) example_fatfs: 0x3ffb4fd0 66 6f 78 20 6a 75 6d 70 65 64 20 6f 76 65 72 20 |fox jumped over | +I (3803) example_fatfs: 0x3ffb4fe0 74 68 65 20 6c 61 7a 79 20 64 6f 67 |the lazy dog| +I (3813) example_fatfs: Test string was found at offset (0x7000) +.... +I (3823) example_fatfs: FAT partition "fat_encrypted" is encrypted. Size is (0x96000 bytes) +.... +I (7303) example_fatfs: Read partition using esp_flash_read at expected offset (0x7000) +I (7303) example_fatfs: 0x3ffb4fb4 3b 8f f4 e1 c1 f4 73 43 d9 28 3f 57 f3 2b d2 b0 |;.....sC.(?W.+..| +I (7313) example_fatfs: 0x3ffb4fc4 41 7a 8f 09 81 1d 92 51 74 8a ee 2a c3 64 8f 75 |Az.....Qt..*.d.u| +I (7323) example_fatfs: 0x3ffb4fd4 61 fe 08 b6 b4 0c cb 08 5a b8 65 29 |a.......Z.e)| +I (7333) example_fatfs: Data does not match test string +``` +If the NVS encryption is enabled, then the output will show the status of the encrypted partition as follows +``` +I (7373) nvs: NVS partition "nvs" is encrypted. +I (7413) example: NVS partition "custom_nvs" is encrypted. +``` + ## Troubleshooting It is also possible to use esptool.py utility to read the eFuse values and check if flash encryption is enabled or not ``` -python $IDF_PATH/components/esptool_py/esptool/espefuse.py --port PORT summary +python $IDF_PATH/components/esptool_py/esptool/espefuse.py --port $PORT summary ``` -If FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets) eFuse value is non-zero flash encryption is enabled +If FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets) eFuse value is non-zero, the flash encryption is enabled + + diff --git a/examples/security/flash_encryption/main/CMakeLists.txt b/examples/security/flash_encryption/main/CMakeLists.txt index 75ea85b111f..13c6fc5328e 100644 --- a/examples/security/flash_encryption/main/CMakeLists.txt +++ b/examples/security/flash_encryption/main/CMakeLists.txt @@ -1,2 +1,3 @@ idf_component_register(SRCS "flash_encrypt_main.c" + "flash_encrypt_fatfs.c" INCLUDE_DIRS ".") diff --git a/examples/security/flash_encryption/main/flash_encrypt_fatfs.c b/examples/security/flash_encryption/main/flash_encrypt_fatfs.c new file mode 100644 index 00000000000..4b4c75f4ab4 --- /dev/null +++ b/examples/security/flash_encryption/main/flash_encrypt_fatfs.c @@ -0,0 +1,192 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Flash encryption 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_flash.h" +#include "esp_partition.h" +#include "esp_vfs.h" +#include "esp_vfs_fat.h" +#include "sdkconfig.h" + +#include "flash_encrypt_fatfs.h" + +static size_t example_fatfs_partition_test(const esp_partition_t* partition, const size_t text_data_offset); + +static const char* TAG = "example_fatfs"; + +void example_read_write_fatfs(void) +{ + const esp_partition_t* partition = NULL; + + // Not encrypted partition test + partition = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_NE); + assert(partition); + + size_t open_test_string_offset = example_fatfs_partition_test(partition, SIZE_MAX); + assert(open_test_string_offset != SIZE_MAX); + + // Encrypted partition test + partition = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_E); + assert(partition); + + example_fatfs_partition_test(partition, open_test_string_offset); +} + +// Performs fatfs test on the partition. +// Erases, formats, writes and reads text file containing "test string". +// Then: +// If parameter text_data_offset == SIZE_MAX, it tries to find test string on the partition using +// esp_partition_read. Returns offset from the beginning of the partition if "test string" is found, otherwise returns SIZE_MAX +// If parameter text_data_offset != SIZE_MAX, it compares the flash content at the text_data_offset with the "test string" +// If data matches, returns text_data_offset, if it doesn't match, returns SIZE_MAX +static size_t example_fatfs_partition_test(const esp_partition_t* partition, const size_t text_data_offset) +{ + const char* TEST_FAT_STRING = "the quick brown fox jumped over the lazy dog"; + // Mount path for the partition + const char *base_path = "/spiflash"; + + // Handle of the wear levelling library instance + wl_handle_t s_wl_handle = WL_INVALID_HANDLE; + esp_err_t err = ESP_FAIL; + + ESP_LOGI(TAG, "FAT partition \"%s\" is %sencrypted. Size is (0x%" PRIx32 " bytes) ", + partition->label, + (partition->encrypted) ? "" : "not ", + (long unsigned int)partition->size + ); + + ESP_LOGI(TAG, "Erasing partition"); + ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); + + ESP_LOGI(TAG, "Formatting FAT filesystem"); + err = esp_vfs_fat_spiflash_format_rw_wl(base_path, partition->label); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to format FATFS (%s)", esp_err_to_name(err)); + return SIZE_MAX; + } + + ESP_LOGI(TAG, "Mounting FAT filesystem"); + // To mount device we need name of device partition, define base_path + // and allow format partition in case if it is new one and was not formatted before + const esp_vfs_fat_mount_config_t mount_config = { + .max_files = 4, + .format_if_mount_failed = false, + .allocation_unit_size = CONFIG_WL_SECTOR_SIZE + }; + err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, partition->label, &mount_config, &s_wl_handle); + + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err)); + return SIZE_MAX; + } + + const size_t RD_BUFF_LEN = 64; + char read_buffer[RD_BUFF_LEN]; + char *device_filename; + + device_filename = "/spiflash/inner.txt"; + + // Open file for writing + ESP_LOGI(TAG, "Opening file"); + FILE *f; + f = fopen(device_filename, "wb"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return SIZE_MAX; + } + fprintf(f, TEST_FAT_STRING); + fclose(f); + + ESP_LOGI(TAG, "Written to file: '%s'", TEST_FAT_STRING); + + // Open file for reading + ESP_LOGI(TAG, "Reading file"); + f = fopen(device_filename, "rb"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for reading"); + return SIZE_MAX; + } + fgets(read_buffer, sizeof(read_buffer), f); + fclose(f); + // strip newline + char *pos = strchr(read_buffer, '\n'); + if (pos) { + *pos = '\0'; + } + ESP_LOGI(TAG, "Read from file: '%s'", read_buffer); + + // Unmount FATFS + ESP_LOGI(TAG, "Unmounting FAT filesystem"); + ESP_ERROR_CHECK(esp_vfs_fat_spiflash_unmount_rw_wl(base_path, s_wl_handle)); + + if (text_data_offset == SIZE_MAX) { + + // try to find the TEST_FAT_STRING on the partition using esp_flash_read read. + ESP_LOGI(TAG, "Read partition using esp_flash_read until test string is found"); + + size_t read_offset = 0; + size_t read_len = RD_BUFF_LEN; + void* text_addr = NULL; + + assert(partition->size > RD_BUFF_LEN); + assert(RD_BUFF_LEN > strlen(TEST_FAT_STRING)); + + // read from partition until it's end + while (true) { + ESP_ERROR_CHECK(esp_flash_read(NULL, read_buffer, partition->address + read_offset, read_len)); + + // try to find characters, break the loop if found + // buffer is read_buffer, len is read_len + text_addr = memmem(read_buffer, read_len, TEST_FAT_STRING, strlen(TEST_FAT_STRING)); + if (text_addr != NULL) { + ESP_LOG_BUFFER_HEXDUMP(TAG, text_addr, strlen(TEST_FAT_STRING), ESP_LOG_INFO); + + // calculate offset from the beginning of the partition + size_t test_str_part_offset = (text_addr - (void*)read_buffer) + read_offset; + ESP_LOGI(TAG, "Test string was found at offset (0x%" PRIx32 ")", (long unsigned int)test_str_part_offset); + return test_str_part_offset; + } + + // advance read buffer by the RD_BUFF_LEN - strlen(TEST_FAT_STRING) + read_offset += (RD_BUFF_LEN - strlen(TEST_FAT_STRING)); + if ((read_offset + strlen(TEST_FAT_STRING)) > partition->size) { + // remaining unread space is not long enough to hold the searched string + break; + } else { + // remaining unread space is either the size of buffer or just the rest up to the end of partition + read_len = (partition->size >= (read_offset + RD_BUFF_LEN)) ? RD_BUFF_LEN : partition->size - read_offset; + } + } + } else { + // offset, where the expected test string should be is in text_data_offset. Try to read it, compare and report + ESP_LOGI(TAG, "Read partition using esp_flash_read at expected offset (0x%" PRIx32 ") ", (long unsigned int)text_data_offset); + + assert(text_data_offset <= partition->size); + assert((text_data_offset + strlen(TEST_FAT_STRING)) <= partition->size); + + // read from flash + ESP_ERROR_CHECK(esp_flash_read(NULL, read_buffer, partition->address + text_data_offset, strlen(TEST_FAT_STRING))); + + ESP_LOG_BUFFER_HEXDUMP(TAG, read_buffer, strlen(TEST_FAT_STRING), ESP_LOG_INFO); + if (memcmp(read_buffer, TEST_FAT_STRING, strlen(TEST_FAT_STRING)) == 0) { + ESP_LOGI(TAG, "Data matches test string"); + return text_data_offset; + } + ESP_LOGI(TAG, "Data does not match test string"); + } + + return SIZE_MAX; +} diff --git a/examples/security/flash_encryption/main/flash_encrypt_fatfs.h b/examples/security/flash_encryption/main/flash_encrypt_fatfs.h new file mode 100644 index 00000000000..ff4e29e3cd9 --- /dev/null +++ b/examples/security/flash_encryption/main/flash_encrypt_fatfs.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Flash encryption 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. +*/ + +#define CUSTOM_FAT_PART_NAME_NE "fat_not_encr" +#define CUSTOM_FAT_PART_NAME_E "fat_encrypted" + +void example_read_write_fatfs(void); diff --git a/examples/security/flash_encryption/main/flash_encrypt_main.c b/examples/security/flash_encryption/main/flash_encrypt_main.c index a38d7c465cf..de290c04b95 100644 --- a/examples/security/flash_encryption/main/flash_encrypt_main.c +++ b/examples/security/flash_encryption/main/flash_encrypt_main.c @@ -19,6 +19,8 @@ #include "esp_efuse_table.h" #include "nvs_flash.h" +#include "flash_encrypt_fatfs.h" + static void example_print_chip_info(void); static void example_print_flash_encryption_status(void); static void example_read_write_flash(void); @@ -35,6 +37,23 @@ static const char* TAG = "example"; #define TARGET_CRYPT_CNT_WIDTH 3 #endif +// return true, if partitions necessary to demonstrate fatfs encryption are present in the flash +static bool can_perform_fatfs_example(void) +{ + const esp_partition_t *fatfs_ne = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_NE); + + const esp_partition_t *fatfs_e = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_E); + + if ((fatfs_ne != NULL) && (fatfs_e != NULL)) { + ESP_LOGI(TAG, "Partitions %s and %s for FATFS example are present", CUSTOM_FAT_PART_NAME_NE, CUSTOM_FAT_PART_NAME_E); + return true; + } + + return false; +} + static esp_err_t example_custom_nvs_part_init(const char *name) { #if CONFIG_NVS_ENCRYPTION @@ -71,6 +90,11 @@ void app_main(void) example_print_chip_info(); example_print_flash_encryption_status(); example_read_write_flash(); + + if (can_perform_fatfs_example()) { + example_read_write_fatfs(); + } + /* Initialize the default NVS partition */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -95,15 +119,15 @@ static void example_print_chip_info(void) uint32_t flash_size; esp_chip_info(&chip_info); printf("This is %s chip with %d CPU core(s), WiFi%s%s, ", - CONFIG_IDF_TARGET, - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + CONFIG_IDF_TARGET, + chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); unsigned major_rev = chip_info.revision / 100; unsigned minor_rev = chip_info.revision % 100; printf("silicon revision v%d.%d, ", major_rev, minor_rev); - if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) { + if (esp_flash_get_size(NULL, &flash_size) != ESP_OK) { printf("Get flash size failed"); return; } @@ -111,7 +135,6 @@ static void example_print_chip_info(void) (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); } - static void example_print_flash_encryption_status(void) { uint32_t flash_crypt_cnt = 0; @@ -123,15 +146,14 @@ static void example_print_flash_encryption_status(void) printf("Flash encryption feature is disabled\n"); } else { printf("Flash encryption feature is enabled in %s mode\n", - mode == ESP_FLASH_ENC_MODE_DEVELOPMENT ? "DEVELOPMENT" : "RELEASE"); + mode == ESP_FLASH_ENC_MODE_DEVELOPMENT ? "DEVELOPMENT" : "RELEASE"); } } - static void example_read_write_flash(void) { const esp_partition_t* partition = esp_partition_find_first( - ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage"); + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage"); assert(partition); printf("Erasing partition \"%s\" (0x%" PRIx32 " bytes)\n", partition->label, partition->size); diff --git a/examples/security/flash_encryption/partitions_example.csv b/examples/security/flash_encryption/partitions_example.csv index 736d14c8774..34e837753f7 100644 --- a/examples/security/flash_encryption/partitions_example.csv +++ b/examples/security/flash_encryption/partitions_example.csv @@ -1,9 +1,12 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, , 0x6000, +nvs, data, nvs, , 0x6000, # Extra partition to demonstrate reading/writing of encrypted flash -storage, data, 0xff, , 0x1000, encrypted -factory, app, factory, , 1M, +storage, data, 0xff, , 0x1000, encrypted +factory, app, factory, , 1M, # nvs_key partition contains the key that encrypts the NVS partition named nvs. The nvs_key partition needs to be encrypted. -nvs_key, data, nvs_keys, , 0x1000, encrypted, +nvs_key, data, nvs_keys, , 0x1000, encrypted, # Custom NVS data partition -custom_nvs, data, nvs, , 0x6000, +custom_nvs, data, nvs, , 0x6000, +# FATFS partitions, one non-encrypted, one encrypted +fat_encrypted, data, fat, , 600k, encrypted +fat_not_encr, data, fat, , 600k, diff --git a/examples/security/flash_encryption/pytest_flash_encryption.py b/examples/security/flash_encryption/pytest_flash_encryption.py index dd1c8fa1a62..3879bbf3500 100644 --- a/examples/security/flash_encryption/pytest_flash_encryption.py +++ b/examples/security/flash_encryption/pytest_flash_encryption.py @@ -53,6 +53,12 @@ def _test_flash_encryption(dut: Dut) -> None: plain_hex_str, 'with esp_flash_read', expected_str, + 'FAT partition "fat_not_encr" is not encrypted.', + 'Read partition using esp_flash_read until test string is found', + 'Test string was found at offset', + 'FAT partition "fat_encrypted" is encrypted.', + 'Read partition using esp_flash_read at expected offset', + 'Data does not match test string', # The status of NVS encryption for the "nvs" partition 'NVS partition "nvs" is encrypted.', # The status of NVS encryption for the "custom_nvs" partition diff --git a/examples/security/flash_encryption/sdkconfig.defaults b/examples/security/flash_encryption/sdkconfig.defaults index 1aa06bec6c1..eebcca2674f 100644 --- a/examples/security/flash_encryption/sdkconfig.defaults +++ b/examples/security/flash_encryption/sdkconfig.defaults @@ -1,5 +1,7 @@ -# This example uses an extra partition to demonstrate encrypted/non-encrypted reads/writes. +# This example uses an extra partitions to demonstrate encrypted/non-encrypted reads/writes. CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" CONFIG_PARTITION_TABLE_OFFSET=0xD000 + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/examples/security/hmac_soft_jtag/README.md b/examples/security/hmac_soft_jtag/README.md index ccc2f523088..9ead91db1fd 100644 --- a/examples/security/hmac_soft_jtag/README.md +++ b/examples/security/hmac_soft_jtag/README.md @@ -46,8 +46,9 @@ espefuse.py -p $ESPPORT burn_key .bin HMAC_DOWN_ALL **Step 4:** Generate token data from the HMAC key. Keep this token data handy before re-enabling JTAG access. ```bash -python jtag_example_helper.py generate_token .bin +python jtag_example_helper.py generate_token .bin ``` +**Note**: The OUTPUT_FILE argument is optional. If provided, the token data will be stored in the specified file in either binary format (.bin) or hexadecimal format (.hex) based on the file extension. If no OUTPUT_FILE is specified, the token data will be printed to the console. ### Configure the project diff --git a/examples/security/hmac_soft_jtag/jtag_example_helper.py b/examples/security/hmac_soft_jtag/jtag_example_helper.py index d355a9d2db2..1674245f898 100644 --- a/examples/security/hmac_soft_jtag/jtag_example_helper.py +++ b/examples/security/hmac_soft_jtag/jtag_example_helper.py @@ -6,15 +6,27 @@ import hmac import os import subprocess +from typing import Optional -def generate_token_data(hmac_key_file: str) -> None: +def generate_token_data(hmac_key_file: str, output_file: Optional[str] = None) -> None: with open(hmac_key_file, 'rb') as file: key_data = file.read() data = bytes([0] * 32) token_data = hmac.HMAC(key_data, data, hashlib.sha256).digest() token_hex = binascii.hexlify(token_data).decode('utf-8') - print(token_hex) + + if output_file: + if output_file.endswith('.bin'): + with open(output_file, 'wb') as out_file: + out_file.write(token_data) + elif output_file.endswith('.hex'): + with open(output_file, 'w') as out_file: + out_file.write(token_hex) + else: + print(f'Unsupported file format for output file: {output_file}') + else: + print(token_hex) def generate_hmac_key(hmac_key_file: str) -> None: @@ -69,6 +81,7 @@ def main() -> None: token_generator_parser = subparsers.add_parser('generate_token') token_generator_parser.add_argument('hmac_key_file', help='File containing the HMAC key') + token_generator_parser.add_argument('output_file', nargs='?', help='File to store the generated token (optional)') args = parser.parse_args() @@ -77,7 +90,7 @@ def main() -> None: elif args.command == 'generate_hmac_key': generate_hmac_key(args.hmac_key_file) elif args.command == 'generate_token': - generate_token_data(args.hmac_key_file) + generate_token_data(args.hmac_key_file, args.output_file) else: parser.print_help() diff --git a/examples/security/security_features_app/CMakeLists.txt b/examples/security/security_features_app/CMakeLists.txt new file mode 100644 index 00000000000..4a35c3aa0f7 --- /dev/null +++ b/examples/security/security_features_app/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(security_features_app) + +target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "${CONFIG_EXAMPLE_SECURE_JTAG_TOKEN_PATH}" TEXT) diff --git a/examples/security/security_features_app/README.md b/examples/security/security_features_app/README.md new file mode 100644 index 00000000000..9272b81c227 --- /dev/null +++ b/examples/security/security_features_app/README.md @@ -0,0 +1,502 @@ +| Supported Targets | ESP32-C3 | +| ----------------- | -------- | + + +# All Secure + +This example demonstrates how to enable all of the available security features on the esp32c3 target at once. +This example shall use combination of host based python tools and firmware for enabling all the related security eFuses. +For simplicity the security features such as Secure Boot V2, Flash Encryption, NVS Encryption shall be enabled through host based python tools (e.g., espefuse). +Some additional security eFuses shall be enabled in the firmware. + +**The device that has followed all the steps mentioned below can be used for production use-cases.** + +> [!CAUTION] +> The instructions in the example directly burn eFuses and once done, it cannot be reverted. Please go through the below steps carefully before executing the example. All the steps must be followed without any changes and in the exact sequence, otherwise the device may end up in an unrecoverable state. + +### Hardware Required + +* A development board with ESP32C3 SoC +* A USB cable for power supply and programming + +**Note: The hardware is not required if you plan to run the example with help of QEMU.** + +## Pre-requisites + +### 1. Set ESPPORT +In the example, we need to use the Serial port in nearly all the commands. To make it easier, we shall set the ESPPORT environment variable at once and reuse it later. See the documentation about [Connecting the ESP device to PC](https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32c3/get-started/establish-serial-connection.html#connect-esp32-c3-to-pc) to find out the Serial port. + +``` +export ESPPORT=/* Serial port to which esp is connected */ +``` + +
+ Setup serial port for QEMU + If you are enabling eFuses on esp32c3 emulated using QEMU then we shall set the serial port as follows: + + export ESPPORT=socket://localhost:5555 + + Please note that this value is set in correspondence with the command to start serial connection with QEMU, do not change the values. + +
+ +**Please make sure to perform this step every time when you open a new terminal to use `esptool/espefuse` commands.** + +### 2. Erase flash + +We shall erase the flash on the device to ensure a clean state. + +```idf.py -p $ESPPORT erase_flash``` + + +### 3. Install esptool +We shall require esptool utility which can be installed as follows: + +```pip install esptool``` + +### 4. Installing qemu (optional) + +If you want to enable the security features on an esp32c3 which has been virtually emulated using qemu then you need to install the necessary packages. + +The detailed instructions on how to use QEMU can be found in the [QEMU documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/tools/qemu.html#qemu-emulator). + + +## Enabling Security Features + +We shall enable the necessary security features one by one as follows: + +### Enabling Secure Boot V2 +For more details about Secure Boot V2 protocol checkout the [Secure boot V2 documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/security/secure-boot-v2.html). + +Please follow below steps to enable Secure Boot V2: + + +1. Generate Signing Key + + ``` + espsecure.py generate_signing_key --version 2 --scheme rsa3072 secure_boot_signing_key.pem + ``` + +2. Generate Public Key Digest + + ``` + espsecure.py digest_sbv2_public_key --keyfile secure_boot_signing_key.pem --output digest.bin + ``` + +3. Burn the key digest in eFuse + + ``` + espefuse.py --port $ESPPORT --chip esp32c3 burn_key BLOCK_KEY0 digest.bin SECURE_BOOT_DIGEST0 + ``` + + where $ESPPORT is the serial port to which the esp32c3 chip is connected. + We have used `BLOCK_KEY0` here to store the Secure Boot V2 digest. Generally, the `BLOCK` can be a free key block from `BLOCK_KE0` to `BLOCK_KEY5`. + + +4. Enable Secure Boot V2 + + ``` + espefuse.py --port $ESPPORT --chip esp32c3 burn_efuse SECURE_BOOT_EN + ``` + +With above steps the Secure Boot V2 feature shall be enabled. The firmware build step is configured to generate signed binaries for `bootloader` and `application` by default (so there is no need to manually sign). +The necessary `security eFuses` are yet to be burned. They shall be burned by the application when first launched. + +#### Use multiple Secure Boot V2 signing keys +**It is recommended to use multiple secure boot v2 signing keys**. + +When the application is built (later in the workflow) the `bootloader` and `application` shall only be signed with the first key. To sign it with multiple keys, please follow below additional steps: + +- Repeat `Step 1` to `Step 3` for `secure_boot_signing_key_2.pem` and `secure_boot_signing_key_3.pem` respectively. +- Sign it with remaining two keys by executing following commands for `secure_boot_signing_key_2.pem` and `secure_boot_signing_key_3.pem` respectively: + + ``` + espsecure.py sign_data --version 2 --keyfile /* Signing key placeholder */ --output bootloader-signed.bin build/bootloader/bootloader.bin + + espsecure.py sign_data --version 2 --keyfile /* Signing key placeholder */ --output my-app-signed.bin build/security_features.bin + ``` + + +### Enabling Flash Encryption + +Details about the Flash Encryption protocol can be found at the [Flash Encryption documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/security/flash-encryption.html) +The indicates the status of Flash Encryption feature for the chip. The example also demonstrates writing and reading encrypted partitions in flash. + +Please follow below steps to enable Flash Encryption: + +1. Generate Flash Encryption keys + + ``` + espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin + ``` + + Note: It is recommended to ensure that the RNG used by host machine to generate the flash encryption key has good entropy + +2. Burn Flash Encryption keys + + ``` + espefuse.py --port $ESPPORT burn_key BLOCK_KEY1 my_flash_encryption_key.bin XTS_AES_128_KEY + ``` + + We have used `BLOCK_KEY1` here to store the Flash Encryption key. Generally, the `BLOCK` can be a free key block from `BLOCK_KE0` to `BLOCK_KEY4`. + +3. Enable Flash Encryption + + ``` + espefuse.py --port $ESPPORT --chip esp32c3 burn_efuse SPI_BOOT_CRYPT_CNT 7 + ``` + +At this point the Flash Encryption feature is enabled for the device. The necessary `security eFuses` shall be enabled by the `security_features` firmware. + +#### Encrypting the partitions +After the application is built (Later in the workflow), all partitions that need encryption can be encrypted with the following command: + +``` +espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address /* Placeholder for partition offset */ --output /* Placeholder for Output File */ /* Placeholder for File to encrypt */ +``` + +The bootloader offset for esp32c3 is `0x0`. The partition table offset for the example has been set to `0xD000` which can be changed through menuconfig. The partition offset for other partitions can be obtained by running ```idf.py partition-table``` + +For this example we need to encrypt only the following 3 partitions: `bootloader.bin`, `partition-table.bin`, `security_features.bin`. + +It can be done with following commands: + +``` +espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x0 --output encrypted_data/bootloader-enc.bin build/bootloader/bootloader.bin + +espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0xD000 --output encrypted_data/partition-table-enc.bin build/partition_table/partition-table.bin + +espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x20000 --output encrypted_data/security_features-enc.bin build/security_features_app.bin +``` + +Please refer to [Encrypted Partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/security/flash-encryption.html#encrypted-partitions) to check which partitions must be encrypted by default. + +### Enabling NVS Encryption + +We shall use the `HMAC based NVS encryption scheme`, Please find more details in the [NVS encryption documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/storage/nvs_encryption.html#nvs-encryption-hmac-peripheral-based-scheme) + +For generation of NVS encryption keys and NVS partition, we shall use [NVS partition generator](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/storage/nvs_partition_gen.html#nvs-partition-generator-utility) +We shall use the [nvs_partition_gen.py](../../../components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py) script for the operations. + +1. Generate HMAC key and NVS encryption key + + ``` + python3 $IDF_PATH/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate-key --keyfile nvs_encr_key.bin --key_protect_hmac --kp_hmac_keygen --kp_hmac_keyfile hmac_key.bin + ``` +2. Burn the HMAC key in eFuse + + ``` + espefuse.py --port $ESPPORT burn_key BLOCK_KEY2 keys/hmac_key.bin HMAC_UP + ``` + + We have used `BLOCK_KEY2` here to store the HMAC key. Generally, `BLOCK` can be a free keyblock between `BLOCK_KEY0` and `BLOCK_KEY5`. + + If you want to change the value of the eFuse key block for this example, make sure to update the same value in `menuconfig → Component config → NVS Security Provider → eFuse key ID storing the HMAC key`. + +3. Generate encrypted NVS partition. + + If you dont want to put external data in the NVS partition then you may skip this step. + See [Generating NVS partition](https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/storage/nvs_partition_gen.html#generate-encrypted-nvs-partition) for detailed information on generating the encrypted NVS partition. + Execute following command to generate the encrypted NVS partition. + + ``` + python3 nvs_partition_gen.py encrypt /* CSV placeholder */ nvs_encr_partition.bin /* NVS partition offset */ --inputkey keys/nvs_encr_key.bin + ``` + * `CSV placeholder`: CSV file which contains data of the NVS partition. See [CSV file format](https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/storage/nvs_partition_gen.html#csv-file-format) for more details. + * `NVS partition offset`: NVS partition offset. Can be found out by executing `idf.py partition-table` + +4. This shall generate `nvs_encr_partition.bin` which we shall flash later at the [Flash stage](README.md#flash) of the workflow. + +### Enabling Secure JTAG Return Material Access (RMA) + +The target provides an ability to disable JTAG access in the device for the software. Which can be re-enabled in future after authentication using a unique token generated beforehand. This way the module can be opened up by bypassing security features after authentication for debugging purposes after it has returned back to the manufacturer due to some issue. This way when a security wise locked device comes back to the ODM/OEM due to some issue, the module can be opened up by bypassing security features after successful authentication. + +1. Generate the HMAC key + + ``` + python3 ../hmac_soft_jtag/jtag_example_helper.py generate_hmac_key secure_jtag_hmac_key.bin + ``` + This key needs to be stored at a secure place in order to re-generate the secure token afterwards. + +2. Generate the secure token + + ``` + python3 ../hmac_soft_jtag/jtag_example_helper.py generate_token secure_jtag_hmac_key.bin secure_jtag_token.bin + ``` + + The example directly consumes this token data and re-enables the software disabled JTAG interface. The re-enablement can be tested by attempting a JTAG connection with the device after JTAG is enabled by the firmware. More details about JTAG debugging can be found [here](https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-guides/jtag-debugging/index.html) + If this is not generated, the example uses a test-only token which is present in the folder. + +3. Burn the key in the eFuse + + ``` + espefuse.py --port $ESPPORT --chip esp32c3 burn_key BLOCK_KEY3 secure_jtag_hmac_key.bin HMAC_DOWN_JTAG + ``` + + We have used `BLOCK_KEY3` here to store the HMAC key. Generally, `BLOCK` can be a free keyblock between `BLOCK_KEY0` and `BLOCK_KEY5`. + +4. Disable software access for JTAG + + ``` + espefuse.py --port $ESPPORT burn_efuse SOFT_DIS_JTAG 7 + ``` + After this the JTAG cannot be accessed before it is re-enabled through software with correct token. + +5. Configuring appropriate JTAG interface + + By default esp32c3 is set to use the [built-in JTAG interface](https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32c3/api-guides/jtag-debugging/configure-builtin-jtag.html). Please follow the steps given [here](https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32c3/api-guides/jtag-debugging/configure-other-jtag.html) to configure the alternative JTAG interface. + Please note that JTAG configuration cannot be done once the application firmware is flashed on the device. + +## Build + +### Set the target + +The target can be set with following command: + +``` +idf.py set-target esp32c3 +``` + +### Build the example + +The example can be built with following command + +``` +idf.py build +``` + +### Secure Boot V2 signing +The example is configured to build the signed binaries for the `bootloader.bin` and `security_features.bin` (application). +These shall be signed with the first secure boot key. + +If you want to use multiple Secure Boot V2 signing keys for the image then please perform the step of [Signing with multiple Secure Boot V2 keys](README.md#use-multiple-secure-boot-v2-signing-keys). + +### Encrypting partitions + +At this point, we shall encrypt all the necessary partitions. Please perform [Encrypting the partitions](README.md#encrypting-the-partitions) step to do the same. + + +## Flash +At this point we shall have all the necessary partitions which are ready to flash. + +The offsets at which the partitions need to be flashed can be found out by executing `idf.py partition-table`. + +The partitions can be flashed with help of the `esptool` utility. + +``` +esptool.py -p $ESPPORT write_flash /* Placeholder for offset */ /* Placeholder for file name */ +``` +Along with these, esptool command may need some additional options. +Please check the output of `idf.py build` command executed earlier for all the necessary options that need to be provided with esptool. + +For this example the following command can be used +``` +esptool.py --chip esp32c3 -b 115200 --before default_reset --after no_reset --no-stub -p $ESPPORT write_flash 0x0 encrypted_data/bootloader-enc.bin 0xd000 encrypted_data/partition-table-enc.bin 0x20000 encrypted_data/security_features-enc.bin --force +``` + +
+ Generate flash image for qemu +In case of qemu the flash image can be generated with help of the following command: + +``` +esptool.py --chip esp32c3 merge_bin --fill-flash-size 4MB -o qemu/security_features_flash_image.bin @qemu/qemu_flash_args +``` +The same file shall be used by the command to execute the image on qemu. + +
+ +## Monitor the output + +Run the monitor tool to view serial output + +``` +idf.py -p $ESPPORT monitor +``` + +## Example Output + +On the first boot-up, there would be prints about firmware not being secure. Please ignore the prints as we shall enable all necessary security eFuses in our application. On the Second boot onwards, you shall not see any such prints. + +### ROM bootloader verifying software bootloader. +``` +ESP-ROM:esp32c3-api1-20210207 +Build:Feb 7 2021 +rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT) +SPIWP:0xee +mode:DIO, clock div:1 +Valid secure boot key blocks: 0 +secure boot verification succeeded +load:0x3fcd5990,len:0x3b94 +load:0x403cc710,len:0xb9c +load:0x403ce710,len:0x5ba8 +entry 0x403cc71a +``` +#### Early logs for Secure Boot V2 and Flash Encryption + +``` +I (101) esp_image: Verifying image signature... +I (106) secure_boot_v2: Verifying with RSA-PSS... +I (107) secure_boot_v2: Signature verified successfully! +I (108) boot: Loaded app from partition at offset 0x20000 +I (109) secure_boot_v2: enabling secure boot v2... +I (109) secure_boot_v2: secure boot v2 is already enabled, continuing.. +I (110) boot: Checking flash encryption... +I (110) flash_encrypt: flash encryption is enabled (0 plaintext flashes left) +I (111) boot: Disabling RNG early entropy source... +``` +#### Flash Encryption warning on first boot (should be ignored) + +``` +W (156) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +E (157) flash_encrypt: Flash encryption settings error: app is configured for RELEASE but efuses are set for DEVELOPMENT +E (160) flash_encrypt: Mismatch found in security options in bootloader menuconfig and efuse settings. Device is not secure. +``` + +#### Unused Secure Boot V2 Digests getting revoked +``` +I (162) efuse: Batch mode of writing fields is enabled +W (163) secure_boot: Unused SECURE_BOOT_DIGEST1 should be revoked. Fixing.. +W (164) secure_boot: Unused SECURE_BOOT_DIGEST2 should be revoked. Fixing.. +I (165) efuse: BURN BLOCK0 +I (175) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (177) efuse: Batch mode. Prepared fields are committed +I (177) secure_boot: Fixed +I (179) efuse: BURN BLOCK0 +I (189) efuse: BURN BLOCK0 - OK (all write block bits are set) +``` + +#### Enablement of relevant security eFuses +``` +W (199) flash_encrypt: Not disabled UART bootloader encryption (set DIS_DOWNLOAD_MANUAL_ENCRYPT->1) +W (199) flash_encrypt: Not disabled UART bootloader cache (set DIS_DOWNLOAD_ICACHE->1) +W (199) flash_encrypt: Not disabled JTAG PADs (set DIS_PAD_JTAG->1) +W (199) flash_encrypt: Not disabled USB JTAG (set DIS_USB_JTAG->1) +W (199) flash_encrypt: Not disabled direct boot mode (set DIS_DIRECT_BOOT->1) +W (199) flash_encrypt: Not write-protected DIS_ICACHE (set WR_DIS_DIS_ICACHE->1) +I (199) flash_encrypt: Disable UART bootloader encryption... +I (199) efuse: BURN BLOCK0 +I (209) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (219) flash_encrypt: Disable UART bootloader cache... +I (219) efuse: BURN BLOCK0 +I (229) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (229) flash_encrypt: Disable JTAG... +I (229) efuse: BURN BLOCK0 +I (239) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (249) efuse: BURN BLOCK0 +I (249) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (259) efuse: BURN BLOCK0 +I (269) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (269) efuse: BURN BLOCK0 +I (279) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (289) efuse: BURN BLOCK0 +I (299) efuse: BURN BLOCK0 - OK (all write block bits are set) +W (299) secure_boot: Not disabled JTAG in the soft way (set SOFT_DIS_JTAG->max) +W (299) secure_boot: Not enabled AGGRESSIVE KEY REVOKE (set SECURE_BOOT_AGGRESSIVE_REVOKE->1) +I (299) secure_boot: Enabling Security download mode... +I (299) secure_boot: Disable hardware & software JTAG... +I (299) efuse: BURN BLOCK0 +I (309) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (319) efuse: BURN BLOCK0 +I (329) efuse: BURN BLOCK0 - OK (all write block bits are set) +I (329) secure_boot: Prevent read disabling of additional efuses... +``` + +#### Final status of Secure Boot V2 and Flash Encryption + +``` +I (329) security_features_app: Flash Encryption is enabled in Release Mode +I (329) security_features_app: Secure Boot is enabled in Release Mode +``` + +#### Flash Encryption demo + +``` +Erasing partition "storage" (0x1000 bytes) +Writing data with esp_partition_write: +I (339) security_features_app: 0x3fc8fa40 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +I (339) security_features_app: 0x3fc8fa50 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +Reading with esp_partition_read: +I (339) security_features_app: 0x3fc8fa60 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +I (339) security_features_app: 0x3fc8fa70 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +Reading with esp_flash_read: +I (339) security_features_app: 0x3fc8fa60 b3 e8 57 98 45 1f 33 de 71 30 71 9b 48 a2 d7 71 |..W.E.3.q0q.H..q| +I (339) security_features_app: 0x3fc8fa70 28 fd fb 54 39 fb 4f 47 be cd 7a e1 55 70 09 6d |(..T9.OG..z.Up.m| +``` + +#### NVS encryption + +These logs show that, the initialisation of the encrypted NVS partitions is successful. +``` +I (349) nvs: NVS partition "nvs" is encrypted. +I (359) security_features_app: NVS partition "custom_nvs" is encrypted. +``` + +## Enable Security Features with help of QEMU + +Espressif fork of [QEMU](https://github.com/espressif/qemu) offers the ability to emulate `esp32c3` target on the host machine with help of `QEMU`. That way all of the above security features can be enabled on the esp32c3 that is emulated on the host machine. A major advantage of this is that no hardware is lost while trying out the security features. + +Below are the commands that can be used to to emulate the esp32c3 device on host machine. + +### Configure eFuse for QEMU + +1. Generate the qemu eFuse file: +A hex file containing the eFuse configuration of ESP32C3 v0.3 (ECO3) has been kept in the same folder. This file can be used to generate the qemu eFuse binary with help of following command. + + ``` + xxd -r -p qemu/efuse_esp32c3.hex qemu/efuse_esp32c3.bin + ``` + +2. Setup serial connection to interact with QEMU + + The below command shall enable a serial connection to the esp32c3 emulated using qemu. The `espefuse` utility when invoked in other terminal can interact with this for performing eFuse related operations. + + + ``` + qemu-system-riscv32 -nographic \ + -machine esp32c3 \ + -drive file=qemu/flash_image.bin,if=mtd,format=raw \ + -global driver=esp32c3.gpio,property=strap_mode,value=0x02 \ + -drive file=qemu/efuse_esp32c3.bin,if=none,format=raw,id=efuse \ + -global driver=nvram.esp32c3.efuse,property=drive,value=efuse \ + -serial tcp::5555,server,nowait + ``` + + This command shall start a serial connection with QEMU. Keep this running in one terminal and execute espefuse commands in an alternate terminal. + + After espefuse commands are used to update the eFuses of the emulated esp the eFuse file generated in *Step 1* shall get ovwewritten. To revert to the original state, execute the command provided in *Step 1* once again. + + +3. Execute the commands to enable security features + + At this point you can execute all the commands mentioned above for [enabling security features](README.md#enabling-security-features). Please keep the above qemu instance running in one terminal and execute all `esptool/espefuse` related commands in a different terminal. + + **For qemu, `before=no_reset` option needs to be provided additionally to every espefuse command. Please make sure you add this just after `-p $ESPPORT` in the command** + + After all the `esptool/espefuse` operations are completed you can close this terminal by pressing `q + Enter` in the same terminal. + +4. Build the example + + Perform the [Build](README.md#build) step and all necessary substeps (e.g. encrypting partition). Please make sure the file names of newly generated files and their locations in the commands are not changed. + +5. Build qemu image + + The qemu image can be built with following command + + ``` + esptool.py --chip esp32c3 merge_bin --fill-flash-size 4MB -o qemu/security_features_flash_image.bin @qemu/qemu_flash_args + ``` + +### Run example on QEMU + +The following command can be used to run example on qemu + +``` +qemu-system-riscv32 -nographic \ + -machine esp32c3 \ + -drive file=qemu/security_features_flash_image.bin,if=mtd,format=raw \ + -drive file=qemu/efuse_esp32c3.bin,if=none,format=raw,id=efuse \ + -global driver=nvram.esp32c3.efuse,property=drive,value=efuse \ + -serial mon:stdio +``` + +The qemu session can be closed by pressing `CTRL+ a` and then immediately pressing `x`. diff --git a/examples/security/security_features_app/encrypted_data/README.md b/examples/security/security_features_app/encrypted_data/README.md new file mode 100644 index 00000000000..466196d14c8 --- /dev/null +++ b/examples/security/security_features_app/encrypted_data/README.md @@ -0,0 +1,3 @@ +# Encrypted data + +This folder shall contain the encrypted files generated with the command. diff --git a/examples/security/security_features_app/main/CMakeLists.txt b/examples/security/security_features_app/main/CMakeLists.txt new file mode 100644 index 00000000000..c9b76807b06 --- /dev/null +++ b/examples/security/security_features_app/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "security_features_app_main.c" + INCLUDE_DIRS "." + REQUIRED_IDF_TARGETS esp32c3) diff --git a/examples/security/security_features_app/main/Kconfig.projbuild b/examples/security/security_features_app/main/Kconfig.projbuild new file mode 100644 index 00000000000..5f6cf77e15a --- /dev/null +++ b/examples/security/security_features_app/main/Kconfig.projbuild @@ -0,0 +1,18 @@ +menu "Example Configuration" + + config EXAMPLE_JTAG_REENABLE_EFUSE_BLOCK + int "JTAG Re-enable efuse key id" + default 3 + range 0 5 + help + The value of the eFuse key id in which the HMAC key is stored for the JTAG re-enablement. + The example readily assumes that the respective hmac key is burned in the eFuse at this value + + config EXAMPLE_SECURE_JTAG_TOKEN_PATH + string "Secure JTAG token path" + default "secure_jtag_token.bin" + help + The path to the binary file containing the token to re-enable JTAG. + This path is relative to the root directory of the example project. + +endmenu diff --git a/examples/security/security_features_app/main/security_features_app_main.c b/examples/security/security_features_app/main/security_features_app_main.c new file mode 100644 index 00000000000..59876fc787e --- /dev/null +++ b/examples/security/security_features_app/main/security_features_app_main.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Flash encryption 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 "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/efuse_reg.h" +#include "esp_efuse.h" +#include "esp_chip_info.h" +#include "esp_flash.h" +#include "esp_partition.h" +#include "esp_flash_encrypt.h" +#include "esp_efuse_table.h" +#include "esp_secure_boot.h" +#include "nvs_flash.h" +#include "nvs_sec_provider.h" +#include "inttypes.h" + +static const char* TAG = "security_features_app"; + +#define CUSTOM_NVS_PART_NAME "custom_nvs" + +extern const uint8_t secure_jtag_token_start[] asm("_binary_secure_jtag_token_bin_start"); +extern const uint8_t secure_jtag_token_end[] asm("_binary_secure_jtag_token_bin_end"); + +#define SECURE_JTAG_TOKEN_LENGTH 32 + +static void example_read_write_flash(void) +{ + const esp_partition_t* partition = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage"); + assert(partition); + + printf("Erasing partition \"%s\" (0x%" PRIx32 " bytes)\n", partition->label, partition->size); + + ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); + + /* Generate the data which will be written */ + const size_t data_size = 32; + uint8_t plaintext_data[data_size]; + for (uint8_t i = 0; i < data_size; ++i) { + plaintext_data[i] = i; + } + + printf("Writing data with esp_partition_write:\n"); + ESP_LOG_BUFFER_HEXDUMP(TAG, plaintext_data, data_size, ESP_LOG_INFO); + ESP_ERROR_CHECK(esp_partition_write(partition, 0, plaintext_data, data_size)); + + uint8_t read_data[data_size]; + printf("Reading with esp_partition_read:\n"); + ESP_ERROR_CHECK(esp_partition_read(partition, 0, read_data, data_size)); + ESP_LOG_BUFFER_HEXDUMP(TAG, read_data, data_size, ESP_LOG_INFO); + + printf("Reading with esp_flash_read:\n"); + ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, partition->address, data_size)); + ESP_LOG_BUFFER_HEXDUMP(TAG, read_data, data_size, ESP_LOG_INFO); +} + +static esp_err_t example_custom_nvs_part_init(const char *name) +{ +#if CONFIG_NVS_ENCRYPTION + esp_err_t ret = ESP_FAIL; + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_config_hmac_t sec_scheme_cfg = NVS_SEC_PROVIDER_CFG_HMAC_DEFAULT(); + ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); + if (ret != ESP_OK) { + return ret; + } + + ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + /* We shall not generate keys here as that must have been done in default NVS partition initialization case */ + ESP_LOGE(TAG, "Failed to read NVS security cfg: [0x%02X] (%s)", ret, esp_err_to_name(ret)); + return ret; + } + + ret = nvs_flash_secure_init_partition(name, &cfg); + if (ret == ESP_OK) { + ESP_LOGI(TAG, "NVS partition \"%s\" is encrypted.", name); + } + return ret; +#else + return nvs_flash_init_partition(name); +#endif +} + +void app_main(void) +{ + bool restart_required = false; + bool sb_release_mode = esp_secure_boot_cfg_verify_release_mode(); + if (!sb_release_mode) { + restart_required = true; + ESP_LOGI(TAG, "Secure Boot V2 not in Release mode\nSetting Release mode..."); + esp_efuse_batch_write_begin(); + if (esp_secure_boot_enable_secure_features() == ESP_OK) { + esp_efuse_batch_write_commit(); + sb_release_mode = esp_secure_boot_cfg_verify_release_mode(); + } else { + esp_efuse_batch_write_cancel(); + } + + if (!sb_release_mode) { + ESP_LOGE(TAG, "Failed to set Secure Boot V2 to Release mode"); + } + } + + bool fe_release_mode = esp_flash_encryption_cfg_verify_release_mode(); + if (!fe_release_mode) { + restart_required = true; + ESP_LOGI(TAG, "Flash encryption not in Release mode\nSetting Release mode..."); + esp_flash_encryption_set_release_mode(); + fe_release_mode = esp_flash_encryption_cfg_verify_release_mode(); + if (!fe_release_mode) { + ESP_LOGE(TAG, "Failed to set Flash Encryption to Release mode"); + } + } + + if (restart_required) { + ESP_LOGI(TAG, "Restarting now"); + esp_restart(); + } + + if (fe_release_mode) { + ESP_LOGI(TAG, "Flash Encryption is enabled in Release Mode"); + } else { + ESP_LOGE(TAG, "Flash Encryption is not enabled in Release mode"); + } + + if (sb_release_mode) { + ESP_LOGI(TAG, "Secure Boot is enabled in Release Mode"); + } else { + ESP_LOGE(TAG, "Secure Boot is not enabled in Release mode"); + } + + example_read_write_flash(); + /* Initialize the default NVS partition */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + /* Initialize the custom NVS partition */ + ret = example_custom_nvs_part_init(CUSTOM_NVS_PART_NAME); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase_partition(CUSTOM_NVS_PART_NAME)); + ret = example_custom_nvs_part_init(CUSTOM_NVS_PART_NAME); + } + ESP_ERROR_CHECK(ret); + ESP_LOGI(TAG, "JTAG Status: Not enabled"); + ESP_LOGI(TAG, "Enabling in .."); + for (int i = 0; i < 5; i++) { + ESP_LOGI(TAG, "%d...", i); + vTaskDelay(1 / portTICK_PERIOD_MS); + } + ESP_LOGI(TAG, "Enabling JTAG"); + size_t secure_jtag_token_length = strlen((const char *)secure_jtag_token_start); + if (secure_jtag_token_length != SECURE_JTAG_TOKEN_LENGTH) { + ESP_LOGE(TAG, "Invalid JTAG token length %d, should be %d", secure_jtag_token_length, SECURE_JTAG_TOKEN_LENGTH); + } + ret = esp_hmac_jtag_enable(CONFIG_EXAMPLE_JTAG_REENABLE_EFUSE_BLOCK, secure_jtag_token_start); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to enable JTAG"); + } + +} diff --git a/examples/security/security_features_app/partitions.csv b/examples/security/security_features_app/partitions.csv new file mode 100644 index 00000000000..c29eb4ecb1f --- /dev/null +++ b/examples/security/security_features_app/partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, , 0x6000, +# Extra partition to demonstrate reading/writing of encrypted flash +storage, data, 0xff, , 0x1000, encrypted +factory, app, factory, , 1M, +# Custom NVS data partition +custom_nvs, data, nvs, , 0x6000, diff --git a/examples/security/security_features_app/qemu/efuse_esp32c3.hex b/examples/security/security_features_app/qemu/efuse_esp32c3.hex new file mode 100644 index 00000000000..4435ec5c83d --- /dev/null +++ b/examples/security/security_features_app/qemu/efuse_esp32c3.hex @@ -0,0 +1,35 @@ +000000000000000000000000000000000000000000000000000000000000 +00000000000000000c000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +00000000 diff --git a/examples/security/security_features_app/qemu/flash_image.bin b/examples/security/security_features_app/qemu/flash_image.bin new file mode 100644 index 00000000000..a1bc830d889 Binary files /dev/null and b/examples/security/security_features_app/qemu/flash_image.bin differ diff --git a/examples/security/security_features_app/qemu/qemu_flash_args b/examples/security/security_features_app/qemu/qemu_flash_args new file mode 100644 index 00000000000..c587939fe2a --- /dev/null +++ b/examples/security/security_features_app/qemu/qemu_flash_args @@ -0,0 +1,5 @@ +--flash_mode dio --flash_freq 80m --flash_size keep + +0x0 encrypted_data/bootloader-enc.bin +0x20000 encrypted_data/security_features-enc.bin +0xd000 encrypted_data/partition-table-enc.bin diff --git a/examples/security/security_features_app/sdkconfig.ci b/examples/security/security_features_app/sdkconfig.ci new file mode 100644 index 00000000000..676e16ab771 --- /dev/null +++ b/examples/security/security_features_app/sdkconfig.ci @@ -0,0 +1,4 @@ +# This file uses insecure configurations for testing purpose +# Do not use this configurations for you project +CONFIG_SECURE_BOOT_SIGNING_KEY="test/test_secure_boot_signing_key.pem" +CONFIG_EXAMPLE_SECURE_JTAG_TOKEN_PATH="test/secure_jtag_token.bin" diff --git a/examples/security/security_features_app/sdkconfig.defaults b/examples/security/security_features_app/sdkconfig.defaults new file mode 100644 index 00000000000..32987b85f3b --- /dev/null +++ b/examples/security/security_features_app/sdkconfig.defaults @@ -0,0 +1,31 @@ +# This example uses an extra partition to demonstrate encrypted/non-encrypted reads/writes. +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0xD000 + +# Secure Boot V2 +CONFIG_SECURE_SIGNED_ON_BOOT=y +CONFIG_SECURE_SIGNED_ON_UPDATE=y +CONFIG_SECURE_SIGNED_APPS=y +CONFIG_SECURE_BOOT_V2_RSA_ENABLED=y +CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=y +CONFIG_SECURE_BOOT=y +CONFIG_SECURE_BOOT_V2_ENABLED=y +CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES=y +CONFIG_SECURE_BOOT_SIGNING_KEY="secure_boot_signing_key.pem" + +CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT=y + +# Please note that this does not make the device insecure as JTAG shall be soft disabled with instructions from README along + +CONFIG_SECURE_BOOT_INSECURE=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y + +# Flash Encryption +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y +CONFIG_SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART=y +CONFIG_SECURE_FLASH_CHECK_ENC_EN_IN_APP=y +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=y diff --git a/examples/security/security_features_app/sdkconfig.defaults.esp32c3 b/examples/security/security_features_app/sdkconfig.defaults.esp32c3 new file mode 100644 index 00000000000..ca0101a3177 --- /dev/null +++ b/examples/security/security_features_app/sdkconfig.defaults.esp32c3 @@ -0,0 +1,8 @@ + +CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE=y + + +# NVS encryption +CONFIG_NVS_ENCRYPTION=y +CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC=y +CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID=2 diff --git a/examples/security/security_features_app/test/secure_jtag_token.bin b/examples/security/security_features_app/test/secure_jtag_token.bin new file mode 100644 index 00000000000..e547179e748 --- /dev/null +++ b/examples/security/security_features_app/test/secure_jtag_token.bin @@ -0,0 +1 @@ + {qػa768Lpg {qػa768LpgŔ1㏉a>z(̍Q \ No newline at end of file diff --git a/examples/security/security_features_app/test/test_hmac_key.bin b/examples/security/security_features_app/test/test_hmac_key.bin new file mode 100644 index 00000000000..63a3db0d80f Binary files /dev/null and b/examples/security/security_features_app/test/test_hmac_key.bin differ diff --git a/examples/security/security_features_app/test/test_nvs_encr_keys.bin b/examples/security/security_features_app/test/test_nvs_encr_keys.bin new file mode 100644 index 00000000000..02faea963f1 --- /dev/null +++ b/examples/security/security_features_app/test/test_nvs_encr_keys.bin @@ -0,0 +1,2 @@ +/f ~=ʝͷiq:+e6 ᯪJ_(l@" +.fn \ No newline at end of file diff --git a/examples/security/security_features_app/test/test_secure_boot_signing_key.pem b/examples/security/security_features_app/test/test_secure_boot_signing_key.pem new file mode 100644 index 00000000000..bce9437fe53 --- /dev/null +++ b/examples/security/security_features_app/test/test_secure_boot_signing_key.pem @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG5AIBAAKCAYEA5Mc7fvPAz9MQl1IqVfRUBWliSZ3GhdW0hM43gOfL2IH/ArS3 +6N8nY6F5Q/3bnvKEfuQ1sAavJwxE+rMJbZGJvOsxf1aSnjJ4GM6yoFtjb6VEpiiP +VLWe4LqFfwluXHhf4w8e38YYJxyKAIc5AS3KPHLLqX+c9UBz3YPw3RUE0kVTHQky +GvOZftfDZoSW7/c9WyqDXg8VavHNyA38y1sKxgR0sqO1wL30TM/RneMC5IjxFQ+Z +P91DIUULiCYBvDBmhX0B7pfB9nevn4Bzjq732WbHYssYI/MIOJq3h9kN2GXQM1Qk +GyX1RGJdc5lN+n0Pi9Fv5K44E97ylwd6F9LxQYwqp1XEbWNCgeCTJpkQ+74Uk/9T +zJrsVzRbIfjbRo7XQHyM1X6tNM9zus3+kL/14ins6lzIVOG9rSUordVrTy+jF1OW +6A0gwnEnNhveruU/IMu7CrpvncSmiHUodctKCDwVFKuD8OQpoBcJOZVM+0JxTu0r +p/UfU7KiA2z2IXbZAgMBAAECggGAM3DY3+LPJ+u9f0jqXAlkGxNnFkZzrQQwYuw7 +brCwFS6luGYKNEJ5CN319mPOTh8Zy65ko//cwlrv5676H7jpz6DSsF82+HtApdNU +NtpVsXTnyrS0BcgQwVcvTTFBr2khplxwBMD2DVVNcnD1UF6LaqwlPyeCk2K6qsRQ +FGX1f5I27gBzU7wSd4LsXNDTX4GoOieFAlFB75oPOzxp6w+9jGjUFJba90u+8saH +y4iPzfM8wg+P1dxai9CKl0J0gWwgNGXMuw0z0OMrGjUYqy9ylAvQOc90xz8D7YHj +OKhwl3kb6O4sQaO7YL7nwptnrML+e5CZ3tosPCQeWVZ3UtCFBaclysO0Nhy5mKbM +xJrGsnquPyRFRglmkngKqbkQQO0ka0X0yrbFZuATE4uxcBF7gBlp+LiHz+1mrimy +Cys2SbRq71e2lNPWlCwnsGL6jADuFYZw2qm3K52Zaj670WtvfUj03fV6ju5kGvdF +6xWszAQJLK0DoVNZB1kNG1nr+VFBAoHBAPgzXUlQXQLmSrvXzJZAIdNVAjcmzAkj +zsSJfv/3Qq30jCMEU75gPxyRYHX6pwS2M1xJMa7jgsf+Eqz8Hr6EDfmg0sA21p2C +dQs2PKIifigPx70dafvtWnQPO+wtxvD/bFhvFt1OFaA1LDwZeCNqSZRqZUksiRv+ +DE4XL8wv6hOudtHV+XD+404YWwJDR+gryX9fDV/6X5guCTUEp6fG+XxCgk9Bu4im +ULoQj3ewfJ3qLyf0e1dcIY1i97vDDb2TTwKBwQDr96Au+U6/d+Q9b57nnUtC+GbY +Qnr2m+LKaVIyn8G3ehoOeAcfnyCJM4QNaIywqF4EdupGrVR1App3/2SjYwrr+0Qi +cGN++dLt5x3kyKcqYUsAQS0uGF1swjfq9SflT2TsUdZo1xZe3IndO4bHV7IdBR9b +p8KMvg27DWml7txRRv+7k7+2zhyEJJ0CdkeTYXMETJow0hkaEw18KGgQUq7muH5c +KkKh5ssdsoRHY/trOm05NY5uxh5jUl4K8lPnaVcCgcEAw+NmINK4Ve2D1jU/VuZO +zAgvs29/YUdNjXgnL8XqbnivkYN8xKgZp2ZlhzfIUcOrTY7HE4ykT0uLWdOyQBLh +JL91Fhcx0yZ/UdYAjMZEY0HxFqT8XMS7uxW66XBHrzUoQbOLjCZwkvzkaJqBYxIj ++GrwfYwUum8LLybFppW6XMY5KOuD71Z798rpKSQIwIiug0R1veZRRD4xLhL6b0Ru +609ioULzy6nX1MH1OTWlZMzLYvFl11Dzei897obHdXOpAoHAZs8rIYxJ/S41aXca +mvtzcShdVtgQTyY4N8yPnbLxaglvFOLC58ojGOQzIsxskAOrgvJ0vHqEk76goqvJ +o05h0dNWKlMhZo9ekXzjD21FODfPv7ql/rFq8xnj1yEdUtG2vSgi7ObZvlcEUjm/ +TVcuKWqz8PE02LFtthPv9fYOU/NFNOr42qMO1ZxGNG5oXRRWUoc1nxPLEAtBEtlg +DcyYm7nChFF9WqD92mCPNbOgNWXtdMGa3zS+xLN8efR/DhJdAoHBAI8j+abPyQDw +0iSi5sx76Abtlb/P8nFZ4Njqf8ojQaytMQGO8DG7e1YMPyq/xIKUVQyFmf8ITx7a +RxlU98sMTiDylVueG2Mx1xNsXlIaX4FDFsvJXUKD4xss4PVv8ZhOgb7uJpd18Op/ +mKfSByfQ/CFjnq+QBBs2KOFyHvwgtJhvn1KddyXFa/E4qEIpjjTZTKfaksweFVCv +GmQ/GFqqd6Ih00Q19bgilpvTDDKjrklkAd0DR13TkLLEGqEaLbjXzA== +-----END RSA PRIVATE KEY----- diff --git a/examples/security/security_features_app/test/test_secure_jtag_token.bin b/examples/security/security_features_app/test/test_secure_jtag_token.bin new file mode 100644 index 00000000000..e547179e748 --- /dev/null +++ b/examples/security/security_features_app/test/test_secure_jtag_token.bin @@ -0,0 +1 @@ + {qػa768Lpg {qػa768LpgŔ1㏉a>z(̍Q \ No newline at end of file diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index cc6f28981be..b7ca9754661 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -113,7 +113,7 @@ examples/storage/perf_benchmark: disable: - if: IDF_TARGET == "esp32c5" temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8704 + reason: not supported yet # TODO: [ESP32C5] IDF-8704, IDF-10314 disable_test: - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] temporary: true @@ -176,3 +176,9 @@ examples/storage/wear_levelling: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: only one target per arch needed + +examples/system/base_mac_address: + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed, runner not burnt efuse # TODO: [ESP32C5] IDF-10337 diff --git a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py index 55743a22316..f9681c42672 100644 --- a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py +++ b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py @@ -5,6 +5,7 @@ @pytest.mark.supported_targets +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not support yet') # TODO: [ESP32C5] IDF-8704, IDF-10314 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 2e9ebc5bbd4..d6196238fed 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -2,11 +2,15 @@ examples/system/app_trace_basic: disable: - - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32p4", "esp32c5"] temporary: true - reason: target esp32c6, esp32h2, esp32p4 is not supported yet + reason: target esp32c6, esp32h2, esp32p4, esp32c5 is not supported yet examples/system/base_mac_address: + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO [ESP32C5] IDF-10347 depends_components: - esp_hw_support @@ -178,7 +182,7 @@ examples/system/ota/native_ota_example: examples/system/ota/otatool: disable: - - if: IDF_TARGET in ["esp32h2"] + - if: IDF_TARGET in ["esp32h2", "esp32c5"] temporary: true reason: target esp32h2 is not supported yet @@ -267,6 +271,8 @@ examples/system/task_watchdog: - esp_system examples/system/ulp/lp_core/gpio: + disable: + - if: SOC_DEEP_SLEEP_SUPPORTED != 1 enable: - if: (SOC_LP_CORE_SUPPORTED == 1) and (SOC_RTCIO_PIN_COUNT > 0) diff --git a/examples/system/app_trace_basic/README.md b/examples/system/app_trace_basic/README.md index 88c1222686f..2da31cd059a 100644 --- a/examples/system/app_trace_basic/README.md +++ b/examples/system/app_trace_basic/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | # Application Level Tracing Example (Basic) diff --git a/examples/system/base_mac_address/pytest_base_mac_address.py b/examples/system/base_mac_address/pytest_base_mac_address.py index 3d7fedb30b0..6e3b61b9f89 100644 --- a/examples/system/base_mac_address/pytest_base_mac_address.py +++ b/examples/system/base_mac_address/pytest_base_mac_address.py @@ -5,6 +5,8 @@ @pytest.mark.supported_targets +# TODO: [ESP32C5] IDF-10337 +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='c5 runners not burnt mac efuse') @pytest.mark.generic def test_base_mac_address(dut: Dut) -> None: def get_hex_r(num_bytes: int) -> str: diff --git a/examples/system/efuse/pytest_system_efuse_example.py b/examples/system/efuse/pytest_system_efuse_example.py index 8ae8d933904..0e650f24d48 100644 --- a/examples/system/efuse/pytest_system_efuse_example.py +++ b/examples/system/efuse/pytest_system_efuse_example.py @@ -49,6 +49,7 @@ def test_examples_efuse_linux(dut: Dut) -> None: @pytest.mark.esp32 @pytest.mark.esp32c2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32s2 @@ -148,6 +149,7 @@ def test_examples_efuse_with_virt_flash_enc_aes_256(dut: Dut) -> None: @pytest.mark.esp32 @pytest.mark.esp32c2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32s2 @@ -223,6 +225,7 @@ def test_examples_efuse_with_virt_flash_enc_pre_loaded(dut: Dut) -> None: @pytest.mark.esp32 @pytest.mark.esp32c2 @pytest.mark.esp32c3 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32s2 @@ -945,6 +948,7 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_qemu(dut: QemuDut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32c2 +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32s2 diff --git a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32.qemu b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32.qemu index e1dde3dd6ff..34762006f96 100644 --- a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32.qemu +++ b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32.qemu @@ -7,7 +7,7 @@ CONFIG_EFUSE_VIRTUAL=n CONFIG_ESP32_REV_MIN_3=y CONFIG_ESP32_REV_MIN=3 -CONFIG_PARTITION_TABLE_OFFSET=0xD000 +CONFIG_PARTITION_TABLE_OFFSET=0xE000 CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv" diff --git a/examples/system/esp_timer/pytest_esp_timer.py b/examples/system/esp_timer/pytest_esp_timer.py index 929df5ccf10..72ac742e8d9 100644 --- a/examples/system/esp_timer/pytest_esp_timer.py +++ b/examples/system/esp_timer/pytest_esp_timer.py @@ -28,6 +28,7 @@ @pytest.mark.supported_targets +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported light sleep') # TODO: [ESP32C5] IDF-8638, IDF-10308 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/examples/system/ipc/ipc_isr/riscv/pytest_ipc_isr_riscv.py b/examples/system/ipc/ipc_isr/riscv/pytest_ipc_isr_riscv.py index 63e87e43070..cd1bba908a4 100644 --- a/examples/system/ipc/ipc_isr/riscv/pytest_ipc_isr_riscv.py +++ b/examples/system/ipc/ipc_isr/riscv/pytest_ipc_isr_riscv.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,7 +7,7 @@ @pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runner') -def test_ipc_isr(dut: Dut) -> None: +def test_ipc_isr_riscv(dut: Dut) -> None: dut.expect_exact('example: Start') dut.expect_exact('example: MSTATUS = 0x3880') dut.expect_exact('example: in[0] = 0x1') diff --git a/examples/system/ipc/ipc_isr/xtensa/pytest_ipc_isr_xtensa.py b/examples/system/ipc/ipc_isr/xtensa/pytest_ipc_isr_xtensa.py index cc3ce4ce804..6a8ecdc40c0 100644 --- a/examples/system/ipc/ipc_isr/xtensa/pytest_ipc_isr_xtensa.py +++ b/examples/system/ipc/ipc_isr/xtensa/pytest_ipc_isr_xtensa.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,7 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s3 @pytest.mark.generic -def test_ipc_isr(dut: Dut) -> None: +def test_ipc_isr_xtensa(dut: Dut) -> None: dut.expect_exact('example: Start') dut.expect_exact('example: PS_INTLEVEL = 0x5') diff --git a/examples/system/light_sleep/pytest_light_sleep.py b/examples/system/light_sleep/pytest_light_sleep.py index 4ac3553b55e..ca40f57ff2d 100644 --- a/examples/system/light_sleep/pytest_light_sleep.py +++ b/examples/system/light_sleep/pytest_light_sleep.py @@ -8,6 +8,7 @@ @pytest.mark.supported_targets +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic def test_light_sleep(dut: Dut) -> None: diff --git a/examples/system/ota/otatool/README.md b/examples/system/ota/otatool/README.md index 2fc4ba3edfb..8ee6bbc5861 100644 --- a/examples/system/ota/otatool/README.md +++ b/examples/system/ota/otatool/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # OTA Tool Example diff --git a/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py b/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py index a9f96aba6c2..3dbcc88c8ea 100644 --- a/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py +++ b/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py @@ -4,6 +4,7 @@ from pytest_embedded import Dut +@pytest.mark.esp32c5 @pytest.mark.esp32c6 @pytest.mark.esp32p4 @pytest.mark.generic diff --git a/export.ps1 b/export.ps1 index fec71aeca72..d519b2296d9 100644 --- a/export.ps1 +++ b/export.ps1 @@ -38,7 +38,7 @@ foreach ($pair in $envars_array) { $var_val = $pair[1].Trim() # trim spaces on the ends of the val if ($var_name -eq "PATH") { # trim "%PATH%" or "`$PATH" - if ($IsWindows || $Windows) { + if ($IsWindows -or $Windows) { $var_val = $var_val.Trim($S + "%PATH%") } else { $var_val = $var_val.Trim($S + "`$PATH") diff --git a/tools/ci/check_copyright_config.yaml b/tools/ci/check_copyright_config.yaml index 0e505ee6032..9850f85dd9c 100644 --- a/tools/ci/check_copyright_config.yaml +++ b/tools/ci/check_copyright_config.yaml @@ -143,7 +143,7 @@ argtable3: md5_hash: include: - - 'components/esp_rom/include/**/rom/md5_hash.h' + - 'components/esp_rom/*/include/**/rom/md5_hash.h' allowed_licenses: - BSD-3-Clause - Apache-2.0 @@ -182,7 +182,7 @@ tinyusb: # with files licensed under a mix of Apache and BSD-3-Clause licenses. esp_rom_usb: include: - - 'components/esp_rom/include/*/rom/usb/' + - 'components/esp_rom/*/include/*/rom/usb/' allowed_licenses: - Apache-2.0 - BSD-3-Clause diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 287137abcb9..b45b0680a9c 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -410,6 +410,7 @@ components/esp_hid/private/bt_hidh.h components/esp_local_ctrl/src/esp_local_ctrl_priv.h components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c components/esp_phy/test/test_phy_rtc.c +components/esp_rom/esp32/include/esp32/rom/tjpgd.h components/esp_rom/esp32/ld/esp32.rom.api.ld components/esp_rom/esp32/ld/esp32.rom.eco3.ld components/esp_rom/esp32/ld/esp32.rom.ld @@ -421,6 +422,7 @@ components/esp_rom/esp32/ld/esp32.rom.newlib-nano.ld components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld components/esp_rom/esp32/ld/esp32.rom.redefined.ld components/esp_rom/esp32/ld/esp32.rom.syscalls.ld +components/esp_rom/esp32c3/include/esp32c3/rom/tjpgd.h components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -428,50 +430,22 @@ components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-nano.ld components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld components/esp_rom/esp32c3/ld/esp32c3.rom.version.ld +components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld components/esp_rom/esp32s2/ld/esp32s2.rom.ld components/esp_rom/esp32s2/ld/esp32s2.rom.libgcc.ld components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-data.ld components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-nano.ld +components/esp_rom/esp32s3/include/esp32s3/rom/opi_flash.h +components/esp_rom/esp32s3/include/esp32s3/rom/tjpgd.h components/esp_rom/esp32s3/ld/esp32s3.rom.api.ld components/esp_rom/esp32s3/ld/esp32s3.rom.ld components/esp_rom/esp32s3/ld/esp32s3.rom.libgcc.ld components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-nano.ld components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld components/esp_rom/esp32s3/ld/esp32s3.rom.version.ld -components/esp_rom/include/esp32/rom/aes.h -components/esp_rom/include/esp32/rom/bigint.h -components/esp_rom/include/esp32/rom/crc.h -components/esp_rom/include/esp32/rom/sha.h -components/esp_rom/include/esp32/rom/tbconsole.h -components/esp_rom/include/esp32/rom/tjpgd.h -components/esp_rom/include/esp32c3/rom/bigint.h -components/esp_rom/include/esp32c3/rom/crc.h -components/esp_rom/include/esp32c3/rom/digital_signature.h -components/esp_rom/include/esp32c3/rom/esp_flash.h -components/esp_rom/include/esp32c3/rom/hmac.h -components/esp_rom/include/esp32c3/rom/rsa_pss.h -components/esp_rom/include/esp32c3/rom/sha.h -components/esp_rom/include/esp32c3/rom/tjpgd.h -components/esp_rom/include/esp32s2/rom/aes.h -components/esp_rom/include/esp32s2/rom/bigint.h -components/esp_rom/include/esp32s2/rom/crc.h -components/esp_rom/include/esp32s2/rom/digital_signature.h -components/esp_rom/include/esp32s2/rom/hmac.h -components/esp_rom/include/esp32s2/rom/opi_flash.h -components/esp_rom/include/esp32s2/rom/rsa_pss.h -components/esp_rom/include/esp32s2/rom/sha.h -components/esp_rom/include/esp32s3/rom/bigint.h -components/esp_rom/include/esp32s3/rom/crc.h -components/esp_rom/include/esp32s3/rom/digital_signature.h -components/esp_rom/include/esp32s3/rom/hmac.h -components/esp_rom/include/esp32s3/rom/opi_flash.h -components/esp_rom/include/esp32s3/rom/rsa_pss.h -components/esp_rom/include/esp32s3/rom/sha.h -components/esp_rom/include/esp32s3/rom/tjpgd.h components/esp_rom/include/esp_rom_crc.h -components/esp_rom/include/linux/soc/reset_reasons.h components/esp_rom/linux/esp_rom_crc.c components/esp_rom/linux/esp_rom_md5.c components/esp_rom/patches/esp_rom_crc.c @@ -687,7 +661,6 @@ components/soc/esp32s3/include/soc/rtc_io_reg.h components/soc/esp32s3/include/soc/rtc_io_struct.h components/soc/esp32s3/include/soc/sdmmc_pins.h components/soc/esp32s3/include/soc/sdmmc_reg.h -components/soc/esp32s3/include/soc/sens_reg.h components/soc/esp32s3/include/soc/sensitive_reg.h components/soc/esp32s3/include/soc/sensitive_struct.h components/soc/esp32s3/include/soc/soc_ulp.h diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index eef90d868b0..faa9bc92d86 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -16,7 +16,6 @@ components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/ components/log/include/esp_log_internal.h -components/esp_rom/include/esp32s2/rom/rsa_pss.h # LWIP: sockets.h uses #include_next<>, which doesn't work correctly with the checker @@ -85,23 +84,23 @@ components/esp_coex/include/private/esp_coexist_adapter.h components/esp_coex/include/esp_coex_i154.h ### To be fixed: headers that rely on implicit inclusion # -components/esp_rom/include/esp32/rom/rtc.h -components/esp_rom/include/esp32c3/rom/rtc.h -components/esp_rom/include/esp32s2/rom/rtc.h -components/esp_rom/include/esp32s3/rom/rtc.h -components/esp_rom/include/esp32c2/rom/rtc.h -components/esp_rom/include/esp32c5/rom/rtc.h -components/esp_rom/include/esp32c6/rom/rtc.h -components/esp_rom/include/esp32h2/rom/rtc.h -components/esp_rom/include/esp32p4/rom/rtc.h -components/esp_rom/include/esp32c61/rom/rtc.h -components/esp_rom/include/esp32/rom/sha.h -components/esp_rom/include/esp32/rom/secure_boot.h -components/esp_rom/include/esp32c3/rom/spi_flash.h -components/esp_rom/include/esp32s2/rom/spi_flash.h -components/esp_rom/include/esp32s2/rom/cache.h -components/esp_rom/include/esp32s2/rom/secure_boot.h -components/esp_rom/include/esp32s2/rom/opi_flash.h +components/esp_rom/esp32/include/esp32/rom/rtc.h +components/esp_rom/esp32c3/include/esp32c3/rom/rtc.h +components/esp_rom/esp32s2/include/esp32s2/rom/rtc.h +components/esp_rom/esp32s3/include/esp32s3/rom/rtc.h +components/esp_rom/esp32c2/include/esp32c2/rom/rtc.h +components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h +components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h +components/esp_rom/esp32h2/include/esp32h2/rom/rtc.h +components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h +components/esp_rom/esp32c61/include/esp32c61/rom/rtc.h +components/esp_rom/esp32/include/esp32/rom/sha.h +components/esp_rom/esp32/include/esp32/rom/secure_boot.h +components/esp_rom/esp32c3/include/esp32c3/rom/spi_flash.h +components/esp_rom/esp32s2/include/esp32s2/rom/spi_flash.h +components/esp_rom/esp32s2/include/esp32s2/rom/cache.h +components/esp_rom/esp32s2/include/esp32s2/rom/secure_boot.h +components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h components/esp_ringbuf/include/freertos/ringbuf.h components/esp_netif/include/esp_netif_defaults.h components/esp_netif/include/esp_netif_net_stack.h @@ -124,8 +123,8 @@ components/spi_flash/include/esp_private/spi_flash_os.h ### To be fixed: files which don't compile for esp32s2 target: components/esp_psram/include/esp32/himem.h -components/esp_rom/include/esp32/rom/ets_sys.h -components/esp_rom/include/esp32/rom/uart.h +components/esp_rom/esp32/include/esp32/rom/ets_sys.h +components/esp_rom/esp32/include/esp32/rom/uart.h ### To be fixed: files which don't compile for esp32s3 target: diff --git a/tools/ci/dynamic_pipelines/templates/known_generate_test_child_pipeline_warnings.yml b/tools/ci/dynamic_pipelines/templates/known_generate_test_child_pipeline_warnings.yml index 42b222e243a..4a7a3730747 100644 --- a/tools/ci/dynamic_pipelines/templates/known_generate_test_child_pipeline_warnings.yml +++ b/tools/ci/dynamic_pipelines/templates/known_generate_test_child_pipeline_warnings.yml @@ -12,6 +12,7 @@ no_runner_tags: - esp32c2,jtag,xtal_40mhz - esp32c3,flash_multi - esp32c3,sdcard_sdmode + - esp32c5,jtag - esp32c6,jtag - esp32h2,jtag - esp32p4,jtag diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 2886b3ac0ac..8959ccec9e6 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -16,7 +16,7 @@ from idf_ci_utils import idf_relpath from pytest_embedded.utils import to_list -SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4'] +SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5'] PREVIEW_TARGETS: t.List[str] = [] # this PREVIEW_TARGETS excludes 'linux' target DEFAULT_SDKCONFIG = 'default' DEFAULT_LOGDIR = 'pytest-embedded' @@ -27,6 +27,7 @@ 'esp32s3': 'support esp32s3 target', 'esp32c3': 'support esp32c3 target', 'esp32c2': 'support esp32c2 target', + 'esp32c5': 'support esp32c5 target', 'esp32c6': 'support esp32c6 target', 'esp32h2': 'support esp32h2 target', 'esp32p4': 'support esp32p4 target', @@ -34,7 +35,8 @@ } SPECIAL_MARKERS = { - 'supported_targets': "support all officially announced supported targets ('esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6')", + 'supported_targets': 'support all officially announced supported targets ' + "('esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32p4', 'esp32c5')", 'preview_targets': "support all preview targets ('none')", 'all_targets': 'support all targets, including supported ones and preview ones', 'temp_skip_ci': 'temp skip tests for specified targets only in ci', diff --git a/tools/idf_py_actions/serial_ext.py b/tools/idf_py_actions/serial_ext.py index bc7218abda2..983731560f3 100644 --- a/tools/idf_py_actions/serial_ext.py +++ b/tools/idf_py_actions/serial_ext.py @@ -9,7 +9,6 @@ from typing import Dict from typing import List from typing import Optional -from typing import Tuple import click from idf_py_actions.errors import FatalError @@ -388,7 +387,7 @@ def secure_generate_flash_encryption_key(action: str, ctx: click.core.Context, a generate_flash_encryption_key_args += ['--keylen', keylen] if extra_args['keyfile']: generate_flash_encryption_key_args += [extra_args['keyfile']] - RunTool('espsecure', generate_flash_encryption_key_args, args.build_dir)() + RunTool('espsecure', generate_flash_encryption_key_args, args.project_dir)() def secure_generate_signing_key(action: str, ctx: click.core.Context, args: PropertyDict, version: str, scheme: str, **extra_args: str) -> None: ensure_build_directory(args, ctx.info_name) @@ -404,10 +403,10 @@ def secure_generate_signing_key(action: str, ctx: click.core.Context, args: Prop if version: generate_signing_key_args += ['--version', version] if scheme: - generate_signing_key_args += ['--scheme', '2'] + generate_signing_key_args += ['--scheme', scheme] if extra_args['keyfile']: generate_signing_key_args += [extra_args['keyfile']] - RunTool('espsecure', generate_signing_key_args, args.build_dir)() + RunTool('espsecure', generate_signing_key_args, args.project_dir)() def secure_sign_data(action: str, ctx: click.core.Context, @@ -439,10 +438,13 @@ def secure_sign_data(action: str, def _parse_efuse_args(ctx: click.core.Context, args: PropertyDict, extra_args: Dict) -> List: efuse_args = [] - efuse_args += ['-p', args.port or get_default_serial_port()] - if args.baud: - efuse_args += ['-b', str(args.baud)] + if args.port: + efuse_args += ['-p', args.port] + elif not args.port and not extra_args['virt']: # if --virt, no port will be found and it would cause error + efuse_args += ['-p', get_default_serial_port()] efuse_args += ['--chip', _get_project_desc(ctx, args)['target']] + if extra_args['virt']: + efuse_args += ['--virt'] if extra_args['before']: efuse_args += ['--before', extra_args['before'].replace('-', '_')] if extra_args['debug']: @@ -469,8 +471,8 @@ def efuse_burn_key(action: str, ctx: click.core.Context, args: PropertyDict, **e burn_key_args += ['--force-write-always'] if extra_args['show_sensitive_info']: burn_key_args += ['--show-sensitive-info'] - if extra_args['image']: - burn_key_args.append(extra_args['image']) + if extra_args['efuse_positional_args']: + burn_key_args += extra_args['efuse_positional_args'] RunTool('espefuse.py', burn_key_args, args.project_dir, build_dir=args.build_dir)() def efuse_dump(action: str, ctx: click.core.Context, args: PropertyDict, file_name: str, **extra_args: Dict) -> None: @@ -489,14 +491,14 @@ def efuse_read_protect(action: str, ctx: click.core.Context, args: PropertyDict, read_protect_args += list(extra_args['efuse_positional_args']) RunTool('espefuse', read_protect_args, args.build_dir)() - def efuse_summary(action: str, ctx: click.core.Context, args: PropertyDict, format: str, **extra_args: Tuple) -> None: + def efuse_summary(action: str, ctx: click.core.Context, args: PropertyDict, format: str, **extra_args: Dict) -> None: ensure_build_directory(args, ctx.info_name) summary_args = [PYTHON, '-m' 'espefuse', 'summary'] summary_args += _parse_efuse_args(ctx, args, extra_args) if format: - summary_args += ['--format', format.replace('-', '_')] - if extra_args['efuses']: - summary_args += extra_args['efuse_name'] + summary_args += [f'--format={format.replace("-", "_")}'] + if extra_args['efuse_name']: + summary_args += [str(extra_args['efuse_name'])] RunTool('espefuse', summary_args, args.build_dir)() def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict, **extra_args: Dict) -> None: @@ -523,7 +525,13 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict } ] - EFUSE_OPTS = BAUD_AND_PORT + [ + EFUSE_OPTS = [PORT] + [ + { + 'names': ['--virt'], + 'is_flag': True, + 'hidden': True, + 'help': 'For host tests, the tool will work in the virtual mode (without connecting to a chip).', + }, { 'names': ['--before'], 'help': 'What to do before connecting to the chip.', @@ -801,6 +809,7 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict 'options': EFUSE_OPTS + [ { 'names': ['--no-protect-key'], + 'is_flag': True, 'help': ( 'Disable default read- and write-protecting of the key.' 'If this option is not set, once the key is flashed it cannot be read back or changed.' @@ -808,6 +817,7 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict }, { 'names': ['--force-write-always'], + 'is_flag': True, 'help': ( "Write the eFuse even if it looks like it's already been written, or is write protected." "Note that this option can't disable write protection, or clear any bit which has already been set." @@ -815,6 +825,7 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict }, { 'names': ['--show-sensitive-info'], + 'is_flag': True, 'help': ( 'Show data to be burned (may expose sensitive data). Enabled if --debug is used.' ), @@ -822,8 +833,8 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict ], 'arguments': [ { - 'names': ['image'], - 'nargs': 1, + 'names': ['efuse-positional-args'], + 'nargs': -1, }, ], }, @@ -865,6 +876,7 @@ def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict { 'names': ['efuse-name'], 'nargs': 1, + 'required': False, }, ], }, diff --git a/tools/test_apps/peripherals/i2c_wifi/pytest_i2c_wifi.py b/tools/test_apps/peripherals/i2c_wifi/pytest_i2c_wifi.py index cbb456562a8..f4f4b37f93a 100644 --- a/tools/test_apps/peripherals/i2c_wifi/pytest_i2c_wifi.py +++ b/tools/test_apps/peripherals/i2c_wifi/pytest_i2c_wifi.py @@ -1,12 +1,15 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded_idf.dut import IdfDut -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4'], reason='h2/p4 does not support wifi') +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 @pytest.mark.generic def test_i2c_wifi_startup(dut: IdfDut) -> None: dut.expect_exact('I2C-WIFI test success') diff --git a/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py b/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py index 14c1a8fab33..569901a065f 100644 --- a/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py +++ b/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py @@ -1,12 +1,15 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded_idf.dut import IdfDut -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4'], reason='h2/p4 not supported') # TODO: IDF-8990 +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize('config', [ 'phy_multiple_init_data', diff --git a/tools/test_apps/system/.build-test-rules.yml b/tools/test_apps/system/.build-test-rules.yml index 8d2ca6ffd4d..cdeed8fac05 100644 --- a/tools/test_apps/system/.build-test-rules.yml +++ b/tools/test_apps/system/.build-test-rules.yml @@ -29,6 +29,12 @@ tools/test_apps/system/eh_frame: temporary: true reason: the other targets are not tested yet +tools/test_apps/system/esp_intr_dump: + disable_test: + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: target test failed # TODO [ESP32C5] IDF-10344 + tools/test_apps/system/g0_components: enable: - if: INCLUDE_DEFAULT == 1 or IDF_TARGET in ["esp32p4", "esp32c5", "esp32c61"] # preview targets @@ -75,7 +81,7 @@ tools/test_apps/system/ram_loadable_app: disable: - if: IDF_TARGET == "esp32c5" temporary: true - reason: not supported # TODO: [ESP32C5] IDF-8644 + reason: not supported # TODO: [ESP32C5] IDF-8644, IDF-10315 disable_test: - if: IDF_TARGET in ["esp32p4"] temporary: true diff --git a/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py b/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py index b4cfd0acf44..16e73e026f4 100644 --- a/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py +++ b/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import os @@ -12,7 +12,7 @@ @pytest.mark.qemu @pytest.mark.host_test def test_esp_intr_dump_nonshared(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_alloc GPIO LEVEL3\n') dut.expect_exact('Allocated GPIO LEVEL3') @@ -26,7 +26,7 @@ def test_esp_intr_dump_nonshared(dut: Dut) -> None: @pytest.mark.qemu @pytest.mark.host_test def test_esp_intr_dump_shared(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_alloc GPIO SHARED\n') dut.expect_exact('Allocated GPIO SHARED') @@ -48,9 +48,11 @@ def test_esp_intr_dump_shared(dut: Dut) -> None: # TODO: IDF-9512, Update the expected output of dual core RISC-V chips when the issue is resolved @pytest.mark.supported_targets +# TODO: [ESP32C5] IDF-10344 +@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='c5 test failed') @pytest.mark.generic def test_esp_intr_dump_expected_output(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_dump\n') exp_out_file = os.path.join(os.path.dirname(__file__), 'expected_output', f'{dut.target}.txt') for line in open(exp_out_file, 'r').readlines(): diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index a5269a0c6ed..3339147b202 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -1050,9 +1050,9 @@ def _test_coredump_summary(dut: PanicTestDut, flash_encrypted: bool, coredump_en dut.expect_elf_sha256('App ELF file SHA256: ') dut.expect_exact('Crashed task: main') if dut.is_xtensa: - dut.expect_exact('Exception cause: 29') + dut.expect_exact('Exception cause: 0') else: - dut.expect_exact('Exception cause: 7') + dut.expect_exact('Exception cause: 2') dut.expect(PANIC_ABORT_PREFIX + r'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$') diff --git a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py index fa770a4c3fd..c1b9b09e3cb 100644 --- a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py +++ b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded_idf.dut import IdfDut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8994 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='esp32p4, esp32c5 support TBD') # TODO: [ESP32P4] IDF-8994 [ESP32C5] IDF-8644, IDF-10315 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['pure_ram',], indirect=True,) @@ -14,7 +13,7 @@ def test_pure_ram_loadable_app(dut: IdfDut) -> None: dut.expect('Time since boot: 3 seconds...', timeout=10) -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8994 +@pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5'], reason='esp32p4, esp32c5 support TBD') # TODO: [ESP32P4] IDF-8994 [ESP32C5] IDF-8644, IDF-10315 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['defaults',], indirect=True,) diff --git a/tools/test_idf_py/test_idf_py.py b/tools/test_idf_py/test_idf_py.py index 0a77a0ab973..7d99776056e 100755 --- a/tools/test_idf_py/test_idf_py.py +++ b/tools/test_idf_py/test_idf_py.py @@ -360,5 +360,182 @@ def test_missing_file(self): self.assertIn('(expansion of @args_non_existent) could not be opened', cm.exception.output.decode('utf-8', 'ignore')) +class TestWrapperCommands(TestCase): + @classmethod + def setUpClass(cls): + cls.sample_project_dir = os.path.join(current_dir, '..', 'test_build_system', 'build_test_app') + os.chdir(cls.sample_project_dir) + super().setUpClass() + + def call_command(self, command: List[str]) -> str: + try: + output = subprocess.check_output( + command, + env=os.environ, + stderr=subprocess.STDOUT).decode('utf-8', 'ignore') + return output + except subprocess.CalledProcessError as e: + self.fail(f'Process should have exited normally, but it exited with a return code of {e.returncode}') + + @classmethod + def tearDownClass(cls): + subprocess.run([sys.executable, idf_py_path, 'fullclean'], stdout=subprocess.DEVNULL) + os.chdir(current_dir) + super().tearDownClass() + + +class TestEFuseCommands(TestWrapperCommands): + """ + Test if wrapper commands for espefuse.py are working as expected. + The goal is NOT to test the functionality of espefuse.py, but to test if the wrapper commands are working as expected. + """ + + def test_efuse_summary(self): + summary_command = [sys.executable, idf_py_path, 'efuse-summary', '--virt'] + output = self.call_command(summary_command) + self.assertIn('EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)', output) + + output = self.call_command(summary_command + ['--format','summary']) + self.assertIn('00:00:00:00:00:00', output) + self.assertIn('MAC address', output) + + output = self.call_command(summary_command + ['--format','value-only', 'WR_DIS']) + self.assertIn('0', output) + + def test_efuse_burn(self): + burn_command = [sys.executable, idf_py_path, 'efuse-burn', '--virt', '--do-not-confirm'] + output = self.call_command(burn_command + ['WR_DIS', '1']) + self.assertIn('\'WR_DIS\' (Efuse write disable mask) 0x0000 -> 0x0001', output) + self.assertIn('Successful', output) + + output = self.call_command(burn_command + ['WR_DIS', '1', 'RD_DIS', '1']) + self.assertIn('WR_DIS', output) + self.assertIn('RD_DIS', output) + self.assertIn('Successful', output) + + def test_efuse_burn_key(self): + key_name = 'efuse_test_key.bin' + subprocess.run([sys.executable, idf_py_path, 'secure-generate-flash-encryption-key', os.path.join(current_dir, key_name)], stdout=subprocess.DEVNULL) + burn_key_command = [sys.executable, idf_py_path, 'efuse-burn-key', '--virt', '--do-not-confirm'] + output = self.call_command(burn_key_command + ['--show-sensitive-info', 'secure_boot_v1', os.path.join(current_dir, key_name)]) + self.assertIn('Burn keys to blocks:', output) + self.assertIn('Successful', output) + + def test_efuse_dump(self): + dump_command = [sys.executable, idf_py_path, 'efuse-dump', '--virt'] + output = self.call_command(dump_command) + self.assertIn('BLOCK0', output) + self.assertIn('BLOCK1', output) + self.assertIn('BLOCK2', output) + self.assertIn('BLOCK3', output) + self.assertIn('read_regs', output) + + def test_efuse_read_protect(self): + read_protect_command = [sys.executable, idf_py_path, 'efuse-read-protect', '--virt', '--do-not-confirm'] + output = self.call_command(read_protect_command + ['MAC_VERSION']) + self.assertIn('MAC_VERSION', output) + self.assertIn('Successful', output) + + def test_efuse_write_protect(self): + write_protect_command = [sys.executable, idf_py_path, 'efuse-write-protect', '--virt', '--do-not-confirm'] + output = self.call_command(write_protect_command + ['WR_DIS']) + self.assertIn('WR_DIS', output) + self.assertIn('Successful', output) + + +class TestSecureCommands(TestWrapperCommands): + """ + Test if wrapper commands for espsecure.py are working as expected. + The goal is NOT to test the functionality of espsecure.py, but to test if the wrapper commands are working as expected. + """ + @classmethod + def setUpClass(cls): + super().setUpClass() + subprocess.run([sys.executable, idf_py_path, 'build'], stdout=subprocess.DEVNULL) + cls.flash_encryption_key = 'test_key.bin' + cls.signing_key = 'test_signing_key.pem' + + def secure_generate_flash_encryption_key(self): + generate_key_command = [sys.executable, idf_py_path, 'secure-generate-flash-encryption-key', self.flash_encryption_key] + output = self.call_command(generate_key_command) + self.assertIn(f'Writing 256 random bits to key file {self.flash_encryption_key}', output) + + def secure_encrypt_flash_data(self): + self.secure_generate_flash_encryption_key() + encrypt_command = [sys.executable, + idf_py_path, + 'secure-encrypt-flash-data', + '--aes-xts', + '--keyfile', + f'../{self.flash_encryption_key}', + '--address', + '0x1000', + '--output', + 'bootloader-enc.bin', + 'bootloader/bootloader.bin'] + output = self.call_command(encrypt_command) + self.assertIn('Using 256-bit key', output) + self.assertIn('Done', output) + + def test_secure_decrypt_flash_data(self): + self.secure_encrypt_flash_data() + decrypt_command = [sys.executable, + idf_py_path, + 'secure-decrypt-flash-data', + '--aes-xts', + '--keyfile', + f'../{self.flash_encryption_key}', + '--address', + '0x1000', + '--output', + 'bootloader-dec.bin', + 'bootloader-enc.bin'] + output = self.call_command(decrypt_command) + self.assertIn('Using 256-bit key', output) + self.assertIn('Done', output) + + def secure_generate_signing_key(self): + generate_key_command = [sys.executable, + idf_py_path, + 'secure-generate-signing-key', + '--version', + '2', + '--scheme', + 'rsa3072', + self.signing_key] + output = self.call_command(generate_key_command) + self.assertIn(f'RSA 3072 private key in PEM format written to {self.signing_key}', output) + self.assertIn('Done', output) + + def secure_sign_data(self): + self.secure_generate_signing_key() + sign_command = [sys.executable, + idf_py_path, + 'secure-sign-data', + '--version', + '2', + '--keyfile', + f'../{self.signing_key}', + '--output', + 'bootloader-signed.bin', + 'bootloader/bootloader.bin'] + output = self.call_command(sign_command) + self.assertIn('Signed', output) + + +class TestMergeBinCommands(TestWrapperCommands): + """ + Test if merge-bin command is invoked as expected. + This test is not testing the functionality of esptool.py merge_bin command, but the invocation of the command from idf.py. + """ + + def test_merge_bin(self): + merge_bin_command = [sys.executable, idf_py_path, 'merge-bin'] + merged_binary_name = 'test-merge-binary.bin' + output = self.call_command(merge_bin_command + ['--output', merged_binary_name]) + self.assertIn(f'file {merged_binary_name}, ready to flash to offset 0x0', output) + self.assertIn(f'Merged binary {merged_binary_name} will be created in the build directory...', output) + + if __name__ == '__main__': main()