From b9550a160928dc8e77f3dc5483c001f3db21f929 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 28 Jun 2023 13:34:52 +0800 Subject: [PATCH 1/6] feat: support cache safe assertion check - Add support for cache safe assertion check to ensure that code expected to be in RAM is in IRAM --- components/esp_hw_support/Kconfig | 10 ++++++ components/esp_hw_support/sleep_modes.c | 47 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 196bec7094..b4c79147bd 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -155,6 +155,16 @@ menu "Hardware Settings" If you are seeing "flash read err, 1000" message printed to the console after deep sleep reset, try increasing this value. + + config ESP_SLEEP_CACHE_SAFE_ASSERTION + bool "Check the cache safety of the sleep wakeup code in sleep process" + default n + help + Enabling it will check the cache safety of the code before the flash power is ready after + light sleep wakeup, and check PM_SLP_IRAM_OPT related code cache safety. This option is + only for code quality inspection. Enabling it will increase the time overhead of entering + and exiting sleep. It is not recommended to enable it in the release version. + endmenu menu "ESP_SLEEP_WORKAROUND" diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index de0ae7203b..1fa427ae63 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -399,6 +399,26 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb) portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); } +#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) \ + || CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION +static int s_cache_suspend_cnt = 0; + +static void IRAM_ATTR suspend_cache(void) { + s_cache_suspend_cnt++; + if (s_cache_suspend_cnt == 1) { + cache_hal_suspend(CACHE_TYPE_ALL); + } +} + +static void IRAM_ATTR resume_cache(void) { + s_cache_suspend_cnt--; + assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops"); + if (s_cache_suspend_cnt == 0) { + cache_hal_resume(CACHE_TYPE_ALL); + } +} +#endif + // [refactor-todo] provide target logic for body of uart functions below static void IRAM_ATTR flush_uarts(void) { @@ -753,6 +773,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif } +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION + if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { + /* Cache Suspend 2: If previous sleep powerdowned the flash, suspend cache here so that the + access to flash before flash ready can be explicitly exposed. */ + suspend_cache(); + } +#endif + #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { rtc_sleep_systimer_enable(true); @@ -897,6 +925,13 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, esp_rom_delay_us(flash_enable_time_us); } +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION + if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { + /* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */ + resume_cache(); + } +#endif + return reject; } @@ -961,6 +996,12 @@ esp_err_t esp_light_sleep_start(void) esp_ipc_isr_stall_other_cpu(); +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT + /* Cache Suspend 0: if CONFIG_PM_SLP_IRAM_OPT is enabled, suspend cache here so that the access to flash + during the sleep process can be explicitly exposed. */ + suspend_cache(); +#endif + // Decide which power domains can be powered down uint32_t pd_flags = get_power_down_flags(); @@ -1113,6 +1154,12 @@ esp_err_t esp_light_sleep_start(void) esp_clk_private_unlock(); esp_timer_private_unlock(); + +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT + /* Cache Resume 0: sleep process done, resume cache for continue running */ + resume_cache(); +#endif + esp_ipc_isr_release_other_cpu(); if (!wdt_was_enabled) { wdt_hal_write_protect_disable(&rtc_wdt_ctx); From 9f993705a6d3c44c3bd2c8aa451076f84fcd1636 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Sun, 25 Jun 2023 17:50:17 +0800 Subject: [PATCH 2/6] fix: wait spi bus idle before hold CS pin - Wait for spi bus idle before holding CS pin to prevent hold selected state during sleep --- components/esp_hw_support/sleep_cpu.c | 4 ---- components/esp_hw_support/sleep_modes.c | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/sleep_cpu.c b/components/esp_hw_support/sleep_cpu.c index eb4cbbdfb1..8ed524e74a 100644 --- a/components/esp_hw_support/sleep_cpu.c +++ b/components/esp_hw_support/sleep_cpu.c @@ -706,10 +706,6 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin { uint32_t mstatus = save_mstatus_and_disable_global_int(); - /* wait cache idle */ - Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); - Cache_Freeze_ICache_Disable(); - cpu_domain_dev_regs_save(s_cpu_retention.retent.plic_frame); cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame); cpu_domain_dev_regs_save(s_cpu_retention.retent.intpri_frame); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 1fa427ae63..fb6b0da1da 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -44,6 +44,7 @@ #include "soc/soc_caps.h" #include "regi2c_ctrl.h" //For `REGI2C_ANA_CALI_PD_WORKAROUND`, temp +#include "hal/cache_hal.h" #include "hal/wdt_hal.h" #include "hal/uart_hal.h" #if SOC_TOUCH_SENSOR_SUPPORTED @@ -746,6 +747,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { + /* Cache Suspend 1: will wait cache idle in cache suspend, also means SPI bus IDLE, then we can hold SPI CS pin safely*/ + suspend_cache(); gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM); } #endif @@ -768,6 +771,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); + /* Cache Resume 1: Resume cache for continue running*/ + resume_cache(); } #endif #endif From 6c14e1de9f134df9e91a2d6e3e720e36950ed249 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 7 Jun 2023 19:50:30 +0800 Subject: [PATCH 3/6] fix: put vddsdio configure api always in iram if pd_flash is enabled - Put vddsdio configure api always in iram if pd_flash is enabled to ensure access flash at flash unavailable time --- components/esp_hw_support/linker.lf | 3 ++- components/esp_pm/linker.lf | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index ba934cc2e9..8e7d4b0d6d 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -15,7 +15,8 @@ entries: rtc_clk (noflash) esp_gpio_reserve: esp_gpio_reserve_pins (noflash) esp_gpio_reserve: esp_gpio_is_pin_reserved (noflash) - if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED: + if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y && (PM_SLP_IRAM_OPT = y || ESP_SLEEP_POWER_DOWN_FLASH = y): + rtc_init:rtc_vddsdio_get_config (noflash) rtc_init:rtc_vddsdio_set_config (noflash) if IDF_TARGET_ESP32C6 = n && IDF_TARGET_ESP32H2 = n: # TODO: IDF-5645 rtc_sleep (noflash_text) diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index f17e24e8a2..12d9282a40 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -13,8 +13,6 @@ entries: sleep_modes:esp_sleep_enable_timer_wakeup (noflash) sleep_modes:timer_wakeup_prepare (noflash) sleep_modes:get_power_down_flags (noflash) - if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED: - rtc_init:rtc_vddsdio_get_config (noflash) esp_clk:esp_clk_slowclk_cal_set (noflash) esp_clk:esp_clk_slowclk_cal_get (noflash) esp_clk:esp_rtc_get_time_us (noflash) From 4e9cc6576356b8592254db19b295652e6376897a Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Sun, 25 Jun 2023 13:43:54 +0800 Subject: [PATCH 4/6] change(uart): change sleep code to be cache safe - Set uart ll with FORCE_INLINE_ATTR - Add no_flash API periph_ll_uart_enabled api --- .../hal/esp32/include/hal/clk_gate_ll.h | 17 ++- .../hal/esp32c2/include/hal/clk_gate_ll.h | 16 ++- .../hal/esp32c3/include/hal/clk_gate_ll.h | 16 ++- .../hal/esp32c6/include/hal/clk_gate_ll.h | 15 ++ components/hal/esp32c6/include/hal/uart_ll.h | 133 +++++++++--------- .../hal/esp32h2/include/hal/clk_gate_ll.h | 17 +++ components/hal/esp32h2/include/hal/uart_ll.h | 127 ++++++++--------- .../hal/esp32s2/include/hal/clk_gate_ll.h | 16 ++- .../hal/esp32s3/include/hal/clk_gate_ll.h | 18 ++- 9 files changed, 241 insertions(+), 134 deletions(-) diff --git a/components/hal/esp32/include/hal/clk_gate_ll.h b/components/hal/esp32/include/hal/clk_gate_ll.h index 8944c22ba2..6455a04431 100644 --- a/components/hal/esp32/include/hal/clk_gate_ll.h +++ b/components/hal/esp32/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,8 +13,10 @@ extern "C" { #include #include #include "esp_attr.h" +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/dport_reg.h" +#include "soc/soc_caps.h" static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) { @@ -264,6 +266,19 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST : + (uart_num == 1) ? DPORT_UART1_RST : + (uart_num == 2) ? DPORT_UART2_RST : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? DPORT_UART_CLK_EN : + (uart_num == 1) ? DPORT_UART1_CLK_EN : + (uart_num == 2) ? DPORT_UART2_CLK_EN : 0); + return DPORT_REG_GET_BIT(DPORT_PERIP_RST_EN_REG, uart_rst_bit) == 0 && + DPORT_REG_GET_BIT(DPORT_PERIP_CLK_EN_REG, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c2/include/hal/clk_gate_ll.h b/components/hal/esp32c2/include/hal/clk_gate_ll.h index aca5cd0569..69355f34f5 100644 --- a/components/hal/esp32c2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c2/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,10 +12,12 @@ extern "C" { #include #include +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/system_reg.h" #include "soc/syscon_reg.h" #include "soc/dport_access.h" +#include "soc/soc_caps.h" #include "esp_attr.h" static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) @@ -213,6 +215,18 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M); DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } + +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : + (uart_num == 1) ? SYSTEM_UART1_RST : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN : + (uart_num == 1) ? SYSTEM_UART1_CLK_EN : 0); + return DPORT_REG_GET_BIT(SYSTEM_PERIP_RST_EN0_REG, uart_rst_bit) == 0 && + DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/include/hal/clk_gate_ll.h b/components/hal/esp32c3/include/hal/clk_gate_ll.h index 0f2c3c299a..3222449055 100644 --- a/components/hal/esp32c3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c3/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,10 +12,12 @@ extern "C" { #include #include +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/system_reg.h" #include "soc/syscon_reg.h" #include "soc/dport_access.h" +#include "soc/soc_caps.h" #include "esp_attr.h" static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) @@ -262,6 +264,18 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M); DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } + +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : + (uart_num == 1) ? SYSTEM_UART1_RST : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN : + (uart_num == 1) ? SYSTEM_UART1_CLK_EN : 0); + return DPORT_REG_GET_BIT(SYSTEM_PERIP_RST_EN0_REG, uart_rst_bit) == 0 && + DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/clk_gate_ll.h b/components/hal/esp32c6/include/hal/clk_gate_ll.h index 96aeecbe83..3df27b2616 100644 --- a/components/hal/esp32c6/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c6/include/hal/clk_gate_ll.h @@ -8,9 +8,11 @@ #include #include +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/pcr_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "esp_attr.h" #ifdef __cplusplus @@ -328,6 +330,19 @@ static inline bool IRAM_ATTR periph_ll_periph_enabled(periph_module_t periph) REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0; } +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG : + (uart_num == 1) ? PCR_UART1_CONF_REG : 0); + uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN : + (uart_num == 1) ? PCR_UART1_RST_EN : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN : + (uart_num == 1) ? PCR_UART1_CLK_EN : 0); + return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 && + REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index aa500f45b5..4432ec3df7 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -10,6 +10,7 @@ #pragma once +#include "esp_attr.h" #include "hal/misc.h" #include "hal/uart_types.h" #include "soc/uart_reg.h" @@ -90,7 +91,7 @@ typedef enum { * @param hw Beginning address of the peripheral registers. * @param source_clk Current LP_UART clock source, one in soc_periph_lp_uart_clk_src_t. */ -static inline void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) +FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) { (void)hw; switch (LP_CLKRST.lpperi.lp_uart_clk_sel) { @@ -114,7 +115,7 @@ static inline void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_ * * @return None. */ -static inline void uart_ll_update(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw) { hw->reg_update.reg_update = 1; while (hw->reg_update.reg_update); @@ -128,7 +129,7 @@ static inline void uart_ll_update(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) +FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { if ((hw) != &LP_UART) { UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); @@ -146,7 +147,7 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) * * @return None. */ -static inline void uart_ll_sclk_enable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) { if ((hw) != &LP_UART) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); @@ -164,7 +165,7 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_sclk_disable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) { if ((hw) != &LP_UART) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); @@ -184,7 +185,7 @@ static inline void uart_ll_sclk_disable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) +FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) { if ((hw) != &LP_UART) { uint32_t sel_value = 0; @@ -218,7 +219,7 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) * * @return None. */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) +FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) { if ((hw) != &LP_UART) { switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { @@ -247,7 +248,7 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk * * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) +FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits @@ -275,7 +276,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t * * @return The current baudrate */ -static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) +FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; @@ -296,7 +297,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) * * @return None */ -static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val |= mask; } @@ -309,7 +310,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return None */ -static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val &= (~mask); } @@ -321,7 +322,7 @@ static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) { return hw->int_raw.val; } @@ -333,7 +334,7 @@ static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) { return hw->int_st.val; } @@ -346,7 +347,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) { hw->int_clr.val = mask; } @@ -358,7 +359,7 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) * * @return interrupt enable value */ -static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) { return hw->int_ena.val; } @@ -372,7 +373,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) +FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) { for (int i = 0; i < (int)rd_len; i++) { buf[i] = hw->fifo.rxfifo_rd_byte; @@ -388,7 +389,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd * * @return None */ -static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) +FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) { for (int i = 0; i < (int)wr_len; i++) { hw->fifo.rxfifo_rd_byte = buf[i]; @@ -402,7 +403,7 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint * * @return None */ -static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw) { hw->conf0_sync.rxfifo_rst = 1; uart_ll_update(hw); @@ -417,7 +418,7 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_txfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) { hw->conf0_sync.txfifo_rst = 1; uart_ll_update(hw); @@ -432,7 +433,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw) * * @return The readable data length in rxfifo. */ -static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) { return (hw->status.rxfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw); } @@ -444,7 +445,7 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) * * @return The data length of txfifo can be written. */ -static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) { uint32_t total_fifo_len = ((hw) == &LP_UART) ? LP_UART_LL_FIFO_DEF_LEN : UART_LL_FIFO_DEF_LEN; uint32_t txfifo_len = (hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw); @@ -459,7 +460,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) +FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) { hw->conf0_sync.stop_bit_num = stop_bit; uart_ll_update(hw); @@ -473,7 +474,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b * * @return None. */ -static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) +FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) { *stop_bit = (uart_stop_bits_t)hw->conf0_sync.stop_bit_num; } @@ -486,7 +487,7 @@ static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_ * * @return None. */ -static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) +FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) { if (parity_mode != UART_PARITY_DISABLE) { hw->conf0_sync.parity = parity_mode & 0x1; @@ -503,7 +504,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) * * @return None. */ -static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) +FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) { if (hw->conf0_sync.parity_en) { *parity_mode = (uart_parity_t)(0x2 | hw->conf0_sync.parity); @@ -521,7 +522,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode * * @return None. */ -static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { hw->conf1.rxfifo_full_thrhd = full_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw); } @@ -535,7 +536,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr * * @return None. */ -static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { hw->conf1.txfifo_empty_thrhd = empty_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw); } @@ -549,7 +550,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t * * @return None. */ -static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) +FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) { hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr; uart_ll_update(hw); @@ -563,7 +564,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) * * @return None. */ -static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) +FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) { hw->idle_conf_sync.tx_idle_num = idle_num; uart_ll_update(hw); @@ -577,7 +578,7 @@ static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) * * @return None. */ -static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) +FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); @@ -597,7 +598,7 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) * * @return None. */ -static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) +FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) { //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { @@ -622,7 +623,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) +FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) { *flow_ctrl = UART_HW_FLOWCTRL_DISABLE; if (hw->hwfc_conf_sync.rx_flow_en) { @@ -642,7 +643,7 @@ static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) +FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) { if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; @@ -671,7 +672,7 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * * * @return None. */ -static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) +FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); @@ -689,7 +690,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch * * @return None. */ -static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) +FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) { hw->conf0_sync.bit_num = data_bit; uart_ll_update(hw); @@ -703,7 +704,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d * * @return None. */ -static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) { hw->conf0_sync.sw_rts = level & 0x1; uart_ll_update(hw); @@ -717,7 +718,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) { hw->conf1.sw_dtr = level & 0x1; } @@ -731,7 +732,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) +FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } @@ -743,7 +744,7 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) * * @return None. */ -static inline void uart_ll_set_mode_normal(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) { // This function is only for HP_UART use // LP_UART can only work in normal mode @@ -763,7 +764,7 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { // This function is only for HP_UART use // LP_UART can only work in normal mode @@ -787,7 +788,7 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { // This function is only for HP_UART use // LP_UART can only work in normal mode @@ -814,7 +815,7 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { // This function is only for HP_UART use // LP_UART can only work in normal mode @@ -839,7 +840,7 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_irda(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw) { // This function is only for HP_UART use // LP_UART can only work in normal mode @@ -861,7 +862,7 @@ static inline void uart_ll_set_mode_irda(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) +FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) { switch (mode) { default: @@ -896,7 +897,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) * * @return None. */ -static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) +FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); @@ -909,7 +910,7 @@ static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, ui * * @return The UART wakeup threshold value. */ -static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) { return hw->sleep_conf2.active_threshold + UART_LL_MIN_WAKEUP_THRESH; } @@ -922,7 +923,7 @@ static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) * * @return The bit mode. */ -static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) +FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) { *data_bit = (uart_word_length_t)hw->conf0_sync.bit_num; } @@ -934,7 +935,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t * * * @return True if the state machine is in the IDLE state, otherwise false is returned. */ -static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) { return ((((hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw)) == 0) && (hw->fsm_status.st_utx_out == 0)); } @@ -946,7 +947,7 @@ static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) * * @return True if hw rts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw) { return hw->hwfc_conf_sync.rx_flow_en; } @@ -958,7 +959,7 @@ static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) * * @return True if hw cts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) { return hw->conf0_sync.tx_flow_en; } @@ -971,13 +972,13 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) +FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) { hw->conf0_sync.loopback = loop_back_en; uart_ll_update(hw); } -static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) +FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; uart_ll_update(hw); @@ -996,7 +997,7 @@ static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) * * @return None. */ -static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) +FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) { // LP_UART does not support UART_SIGNAL_IRDA_TX_INV and UART_SIGNAL_IRDA_RX_INV // lp_uart_dev_t has no these fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1027,7 +1028,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) * * @return None. */ -static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) +FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) { uint16_t tout_val = tout_thrd; if(tout_thrd > 0) { @@ -1046,7 +1047,7 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) * * @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0. */ -static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) { uint16_t tout_thrd = 0; if(hw->tout_conf_sync.rx_tout_en > 0) { @@ -1062,7 +1063,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) * * @return maximum timeout threshold. */ -static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) { return ((hw) == &LP_UART) ? LP_UART_RX_TOUT_THRHD_V : UART_RX_TOUT_THRHD_V; } @@ -1073,7 +1074,7 @@ static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) * @param hw Beginning address of the peripheral registers. * @param enable Boolean marking whether the auto baudrate should be enabled or not. */ -static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) +FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) { // LP_UART does not support autobaud // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1087,7 +1088,7 @@ static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) { // LP_UART does not support this feature // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1100,7 +1101,7 @@ static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) { // LP_UART does not support this feature // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1113,7 +1114,7 @@ static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) { // LP_UART does not support this feature // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1126,7 +1127,7 @@ static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) { // LP_UART does not support this feature // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1139,7 +1140,7 @@ static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) { // LP_UART does not support this feature // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct @@ -1154,7 +1155,7 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_force_xoff(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) { uart_dev_t *hw = UART_LL_GET_HW(uart_num); hw->swfc_conf0_sync.force_xon = 0; @@ -1170,7 +1171,7 @@ static inline void uart_ll_force_xoff(uart_port_t uart_num) * * @return None. */ -static inline void uart_ll_force_xon(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) { uart_dev_t *hw = UART_LL_GET_HW(uart_num); hw->swfc_conf0_sync.force_xoff = 0; @@ -1187,7 +1188,7 @@ static inline void uart_ll_force_xon(uart_port_t uart_num) * * @return UART module FSM status. */ -static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) +FORCE_INLINE_ATTR uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) { uart_dev_t *hw = UART_LL_GET_HW(uart_num); return hw->fsm_status.st_utx_out; @@ -1200,7 +1201,7 @@ static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) * @param discard true: Receiver stops storing data into FIFO when data is wrong * false: Receiver continue storing data into FIFO when data is wrong */ -static inline void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) +FORCE_INLINE_ATTR void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) { hw->conf0_sync.err_wr_mask = discard ? 1 : 0; uart_ll_update(hw); diff --git a/components/hal/esp32h2/include/hal/clk_gate_ll.h b/components/hal/esp32h2/include/hal/clk_gate_ll.h index f45fead764..19ba4c2aff 100644 --- a/components/hal/esp32h2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32h2/include/hal/clk_gate_ll.h @@ -8,9 +8,12 @@ #include #include +#include "esp_attr.h" +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/pcr_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -390,6 +393,20 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) // DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M);// ESP32H2-TODO: IDF-6400 // DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } + +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG : + (uart_num == 1) ? PCR_UART1_CONF_REG : 0); + uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN : + (uart_num == 1) ? PCR_UART1_RST_EN : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN : + (uart_num == 1) ? PCR_UART1_CLK_EN : 0); + return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 && + REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/uart_ll.h b/components/hal/esp32h2/include/hal/uart_ll.h index 60e635973a..96abc79cb5 100644 --- a/components/hal/esp32h2/include/hal/uart_ll.h +++ b/components/hal/esp32h2/include/hal/uart_ll.h @@ -11,6 +11,7 @@ #pragma once #include +#include "esp_attr.h" #include "hal/misc.h" #include "hal/uart_types.h" #include "soc/uart_reg.h" @@ -100,7 +101,7 @@ FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) +FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); } @@ -112,7 +113,7 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) * * @return None. */ -static inline void uart_ll_sclk_enable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); } @@ -124,7 +125,7 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_sclk_disable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); } @@ -138,7 +139,7 @@ static inline void uart_ll_sclk_disable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) +FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) { switch (source_clk) { case UART_SCLK_PLL_F48M: @@ -164,7 +165,7 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) * * @return None. */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) +FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk) { switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { default: @@ -189,7 +190,7 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk * * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) +FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits @@ -213,7 +214,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t * * @return The current baudrate */ -static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) +FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; @@ -228,7 +229,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) * * @return None */ -static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val |= mask; } @@ -241,7 +242,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return None */ -static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val &= (~mask); } @@ -253,7 +254,7 @@ static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) { return hw->int_raw.val; } @@ -265,7 +266,7 @@ static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) { return hw->int_st.val; } @@ -278,7 +279,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) { hw->int_clr.val = mask; } @@ -290,7 +291,7 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) * * @return interrupt enable value */ -static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) { return hw->int_ena.val; } @@ -304,7 +305,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) +FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) { for (int i = 0; i < (int)rd_len; i++) { buf[i] = hw->fifo.rxfifo_rd_byte; @@ -320,7 +321,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd * * @return None */ -static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) +FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) { for (int i = 0; i < (int)wr_len; i++) { hw->fifo.rxfifo_rd_byte = buf[i]; @@ -334,7 +335,7 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint * * @return None */ -static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw) { hw->conf0_sync.rxfifo_rst = 1; uart_ll_update(hw); @@ -349,7 +350,7 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_txfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) { hw->conf0_sync.txfifo_rst = 1; uart_ll_update(hw); @@ -364,7 +365,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw) * * @return The readable data length in rxfifo. */ -static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) { return hw->status.rxfifo_cnt; } @@ -376,7 +377,7 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) * * @return The data length of txfifo can be written. */ -static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) { return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt; } @@ -389,7 +390,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) +FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) { hw->conf0_sync.stop_bit_num = stop_bit; uart_ll_update(hw); @@ -403,7 +404,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b * * @return None. */ -static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) +FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) { *stop_bit = (uart_stop_bits_t)hw->conf0_sync.stop_bit_num; } @@ -416,7 +417,7 @@ static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_ * * @return None. */ -static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) +FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) { if (parity_mode != UART_PARITY_DISABLE) { hw->conf0_sync.parity = parity_mode & 0x1; @@ -433,7 +434,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) * * @return None. */ -static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) +FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) { if (hw->conf0_sync.parity_en) { *parity_mode = (uart_parity_t)(0x2 | hw->conf0_sync.parity); @@ -451,7 +452,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode * * @return None. */ -static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { hw->conf1.rxfifo_full_thrhd = full_thrhd; } @@ -465,7 +466,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr * * @return None. */ -static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { hw->conf1.txfifo_empty_thrhd = empty_thrhd; } @@ -479,7 +480,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t * * @return None. */ -static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) +FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) { hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr; uart_ll_update(hw); @@ -493,7 +494,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) * * @return None. */ -static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) +FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) { hw->idle_conf_sync.tx_idle_num = idle_num; uart_ll_update(hw); @@ -507,7 +508,7 @@ static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) * * @return None. */ -static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) +FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); @@ -527,7 +528,7 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) * * @return None. */ -static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) +FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) { //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { @@ -552,7 +553,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) +FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) { *flow_ctrl = UART_HW_FLOWCTRL_DISABLE; if (hw->hwfc_conf_sync.rx_flow_en) { @@ -572,7 +573,7 @@ static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) +FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) { if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; @@ -601,7 +602,7 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * * * @return None. */ -static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) +FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); @@ -619,7 +620,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch * * @return None. */ -static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) +FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) { hw->conf0_sync.bit_num = data_bit; uart_ll_update(hw); @@ -633,7 +634,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d * * @return None. */ -static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) { hw->conf0_sync.sw_rts = level & 0x1; uart_ll_update(hw); @@ -647,7 +648,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) { hw->conf1.sw_dtr = level & 0x1; } @@ -661,7 +662,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) +FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } @@ -673,7 +674,7 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) * * @return None. */ -static inline void uart_ll_set_mode_normal(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; @@ -689,7 +690,7 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { // Application software control, remove echo hw->rs485_conf_sync.rs485rxby_tx_en = 1; @@ -709,7 +710,7 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { // Enable receiver, sw_rts = 1 generates low level on RTS pin hw->conf0_sync.sw_rts = 1; @@ -732,7 +733,7 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { hw->conf0_sync.irda_en = 0; // Enable full-duplex mode @@ -753,7 +754,7 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_irda(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; @@ -771,7 +772,7 @@ static inline void uart_ll_set_mode_irda(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) +FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) { switch (mode) { default: @@ -802,7 +803,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) * * @return None. */ -static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) +FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); @@ -815,7 +816,7 @@ static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, ui * * @return The UART wakeup threshold value. */ -static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) { return hw->sleep_conf2.active_threshold + UART_LL_MIN_WAKEUP_THRESH; } @@ -828,7 +829,7 @@ static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) * * @return The bit mode. */ -static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) +FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) { *data_bit = (uart_word_length_t)hw->conf0_sync.bit_num; } @@ -840,7 +841,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t * * * @return True if the state machine is in the IDLE state, otherwise false is returned. */ -static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) { return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0)); } @@ -852,7 +853,7 @@ static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) * * @return True if hw rts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw) { return hw->hwfc_conf_sync.rx_flow_en; } @@ -864,7 +865,7 @@ static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) * * @return True if hw cts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) { return hw->conf0_sync.tx_flow_en; } @@ -877,13 +878,13 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) +FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) { hw->conf0_sync.loopback = loop_back_en; uart_ll_update(hw); } -static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) +FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; uart_ll_update(hw); @@ -902,7 +903,7 @@ static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) * * @return None. */ -static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) +FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) { typeof(hw->conf0_sync) conf0_reg; conf0_reg.val = hw->conf0_sync.val; @@ -930,7 +931,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) * * @return None. */ -static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) +FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) { uint16_t tout_val = tout_thrd; if(tout_thrd > 0) { @@ -949,7 +950,7 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) * * @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0. */ -static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) { uint16_t tout_thrd = 0; if(hw->tout_conf_sync.rx_tout_en > 0) { @@ -965,7 +966,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) * * @return maximum timeout threshold. */ -static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) { return UART_RX_TOUT_THRHD_V; } @@ -976,7 +977,7 @@ static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) * @param hw Beginning address of the peripheral registers. * @param enable Boolean marking whether the auto baudrate should be enabled or not. */ -static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) +FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) { hw->conf0_sync.autobaud_en = enable ? 1 : 0; uart_ll_update(hw); @@ -987,7 +988,7 @@ static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) { return hw->rxd_cnt.rxd_edge_cnt; } @@ -997,7 +998,7 @@ static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) { return hw->pospulse.posedge_min_cnt; } @@ -1007,7 +1008,7 @@ static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) { return hw->negpulse.negedge_min_cnt; } @@ -1017,7 +1018,7 @@ static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) { return hw->highpulse.highpulse_min_cnt; } @@ -1027,7 +1028,7 @@ static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) { return hw->lowpulse.lowpulse_min_cnt; } @@ -1039,7 +1040,7 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_force_xoff(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); @@ -1068,7 +1069,7 @@ FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) * * @return UART module FSM status. */ -static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) +FORCE_INLINE_ATTR uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) { return REG_GET_FIELD(UART_FSM_STATUS_REG(uart_num), UART_ST_UTX_OUT); } @@ -1080,7 +1081,7 @@ static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) * @param discard true: Receiver stops storing data into FIFO when data is wrong * false: Receiver continue storing data into FIFO when data is wrong */ -static inline void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) +FORCE_INLINE_ATTR void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) { hw->conf0_sync.err_wr_mask = discard ? 1 : 0; uart_ll_update(hw); diff --git a/components/hal/esp32s2/include/hal/clk_gate_ll.h b/components/hal/esp32s2/include/hal/clk_gate_ll.h index a1ef5be97a..28c9787f13 100644 --- a/components/hal/esp32s2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s2/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,10 +13,12 @@ extern "C" { #include #include #include "esp_attr.h" +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/system_reg.h" #include "soc/syscon_reg.h" #include "soc/dport_access.h" +#include "soc/soc_caps.h" static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) { @@ -276,6 +278,18 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN_M); DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } + +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST : + (uart_num == 1) ? DPORT_UART1_RST : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? DPORT_UART_CLK_EN : + (uart_num == 1) ? DPORT_UART1_CLK_EN : 0); + return DPORT_REG_GET_BIT(DPORT_PERIP_RST_EN_REG, uart_rst_bit) == 0 && + DPORT_REG_GET_BIT(DPORT_PERIP_CLK_EN_REG, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/clk_gate_ll.h b/components/hal/esp32s3/include/hal/clk_gate_ll.h index 38a0539aa8..0d2a2b1872 100644 --- a/components/hal/esp32s3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s3/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,10 +13,12 @@ extern "C" { #include #include #include "esp_attr.h" +#include "hal/assert.h" #include "soc/periph_defs.h" #include "soc/system_reg.h" #include "soc/syscon_reg.h" #include "soc/dport_access.h" +#include "soc/soc_caps.h" static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) { @@ -297,6 +299,20 @@ static inline void periph_ll_wifi_module_disable_clk_set_rst(void) DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M); DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } + +FORCE_INLINE_ATTR bool periph_ll_uart_enabled(uint32_t uart_num) +{ + HAL_ASSERT(uart_num < SOC_UART_HP_NUM); + uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : + (uart_num == 1) ? SYSTEM_UART1_RST : + (uart_num == 2) ? SYSTEM_UART2_RST : 0); + uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN : + (uart_num == 1) ? SYSTEM_UART1_CLK_EN : + (uart_num == 2) ? SYSTEM_UART2_CLK_EN : 0); + return DPORT_REG_GET_BIT(SYSTEM_PERIP_RST_EN0_REG, uart_rst_bit) == 0 && + DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0; +} + #ifdef __cplusplus } #endif From a5c992c8afbfce0e698afefde259a5566fbfdef2 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Sun, 25 Jun 2023 17:12:43 +0800 Subject: [PATCH 5/6] fix(esp_pm): fix PM_SLP_IRAM_OPT/PM_RTOS_IDLE_OPT feature - Fix flash accessed code to resolve issues with PM_SLP_IRAM_OPT/PM_RTOS_IDLE_OPT enabled --- components/esp_hw_support/Kconfig | 7 ++-- components/esp_hw_support/intr_alloc.c | 4 +-- components/esp_hw_support/linker.lf | 8 +++-- components/esp_hw_support/modem_clock.c | 2 +- .../esp_hw_support/port/esp32c2/rtc_sleep.c | 7 ++-- .../esp_hw_support/port/esp32c3/rtc_sleep.c | 7 ++-- .../esp_hw_support/port/esp32s3/rtc_sleep.c | 7 ++-- components/esp_hw_support/sleep_clock.c | 2 +- components/esp_hw_support/sleep_modem.c | 2 +- components/esp_hw_support/sleep_modes.c | 34 +++++++++++-------- .../esp_hw_support/sleep_system_peripheral.c | 2 +- components/esp_pm/Kconfig | 8 ++--- components/esp_pm/linker.lf | 17 ++++++++++ components/hal/esp32c6/modem_clock_hal.c | 4 +-- components/hal/esp32c6/pmu_hal.c | 8 ++--- components/hal/esp32h2/modem_clock_hal.c | 2 +- components/hal/esp32h2/pmu_hal.c | 8 ++--- components/hal/esp32s3/include/hal/uart_ll.h | 2 +- components/hal/linker.lf | 2 ++ 19 files changed, 81 insertions(+), 52 deletions(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index b4c79147bd..c521e6311b 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -72,8 +72,7 @@ menu "Hardware Settings" config ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND bool "Pull-up Flash CS pin in light sleep" - depends on !APP_BUILD_TYPE_PURE_RAM_APP && !ESP_SLEEP_POWER_DOWN_FLASH \ - && !PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + depends on !APP_BUILD_TYPE_PURE_RAM_APP && !ESP_SLEEP_POWER_DOWN_FLASH default y help All IOs will be set to isolate(floating) state by default during sleep. @@ -89,7 +88,7 @@ menu "Hardware Settings" config ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND bool "Pull-up PSRAM CS pin in light sleep" - depends on SPIRAM && !PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + depends on SPIRAM default y help All IOs will be set to isolate(floating) state by default during sleep. @@ -105,7 +104,7 @@ menu "Hardware Settings" config ESP_SLEEP_MSPI_NEED_ALL_IO_PU bool "Pull-up all SPI pins in light sleep" - depends on !ESP_SLEEP_POWER_DOWN_FLASH && !PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP \ + depends on !ESP_SLEEP_POWER_DOWN_FLASH \ && (ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND || ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32S3 help diff --git a/components/esp_hw_support/intr_alloc.c b/components/esp_hw_support/intr_alloc.c index 40434232ed..abcee04358 100644 --- a/components/esp_hw_support/intr_alloc.c +++ b/components/esp_hw_support/intr_alloc.c @@ -893,12 +893,12 @@ void IRAM_ATTR ets_isr_mask(uint32_t mask) { esp_cpu_intr_disable(mask); } -void esp_intr_enable_source(int inum) +void IRAM_ATTR esp_intr_enable_source(int inum) { esp_cpu_intr_enable(1 << inum); } -void esp_intr_disable_source(int inum) +void IRAM_ATTR esp_intr_disable_source(int inum) { esp_cpu_intr_disable(1 << inum); } diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 8e7d4b0d6d..134e3ba8d9 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -23,8 +23,6 @@ entries: rtc_time (noflash_text) if SOC_PMU_SUPPORTED = y: pmu_sleep (noflash) - if PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32 = n: - sleep_modem:periph_inform_out_light_sleep_overhead (noflash) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: rtc_wdt (noflash_text) if PERIPH_CTRL_FUNC_IN_IRAM = y: @@ -44,3 +42,9 @@ entries: sar_periph_ctrl (noflash) else: sar_periph_ctrl: sar_periph_ctrl_power_enable (noflash) + +[mapping:soc_pm] +archive: libsoc.a +entries: + if PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND: + gpio_periph: GPIO_HOLD_MASK (noflash) diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index 715a8ac211..e9143b544b 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -283,7 +283,7 @@ void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module) #define COEXIST_CLOCK_DEPS (BIT(MODEM_CLOCK_COEXIST)) #define PHY_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER) | BIT(MODEM_CLOCK_FE)) -static inline uint32_t modem_clock_get_module_deps(periph_module_t module) +static IRAM_ATTR uint32_t modem_clock_get_module_deps(periph_module_t module) { uint32_t deps = 0; if (module == PERIPH_PHY_MODULE) {deps = PHY_CLOCK_DEPS;} diff --git a/components/esp_hw_support/port/esp32c2/rtc_sleep.c b/components/esp_hw_support/port/esp32c2/rtc_sleep.c index 325a22699f..6b6f08d0a6 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c2/rtc_sleep.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -21,6 +22,8 @@ #include "soc/regi2c_lp_bias.h" #include "soc/regi2c_dig_reg.h" +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered down in deep sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -143,7 +146,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } @@ -229,7 +231,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject; diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index 97d7c866e3..765ad28387 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -27,6 +28,8 @@ #include "soc/systimer_reg.h" #endif +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered down in deep sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -168,7 +171,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } if (cfg.wifi_pd_en) { @@ -368,7 +370,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject; diff --git a/components/esp_hw_support/port/esp32s3/rtc_sleep.c b/components/esp_hw_support/port/esp32s3/rtc_sleep.c index 836a484602..4033f2f781 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s3/rtc_sleep.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -20,6 +21,8 @@ #define RTC_CNTL_MEM_FOLW_CPU (RTC_CNTL_SLOWMEM_FOLW_CPU | RTC_CNTL_FASTMEM_FOLW_CPU) +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered up in sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -171,7 +174,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } @@ -289,7 +291,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index 86e2b15ff4..6b12e298ec 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -76,7 +76,7 @@ void sleep_clock_modem_retention_deinit(void) sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); } -bool IRAM_ATTR clock_domain_pd_allowed(void) +bool clock_domain_pd_allowed(void) { const uint32_t modules = sleep_retention_get_modules(); const uint32_t mask = (const uint32_t) ( diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index 1db50733e4..adb42b488b 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -275,7 +275,7 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void #endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */ -bool IRAM_ATTR modem_domain_pd_allowed(void) +bool modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA const uint32_t modules = sleep_retention_get_modules(); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index fb6b0da1da..a513570e2a 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -400,10 +400,11 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb) portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); } -#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) \ +#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND && !CONFIG_IDF_TARGET_ESP32H2) \ || CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION static int s_cache_suspend_cnt = 0; +// Must be called from critical sections. static void IRAM_ATTR suspend_cache(void) { s_cache_suspend_cnt++; if (s_cache_suspend_cnt == 1) { @@ -411,9 +412,10 @@ static void IRAM_ATTR suspend_cache(void) { } } +// Must be called from critical sections. static void IRAM_ATTR resume_cache(void) { s_cache_suspend_cnt--; - assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops"); + assert(s_cache_suspend_cnt >= 0 && DRAM_STR("cache resume doesn't match suspend ops")); if (s_cache_suspend_cnt == 0) { cache_hal_resume(CACHE_TYPE_ALL); } @@ -427,7 +429,7 @@ static void IRAM_ATTR flush_uarts(void) #ifdef CONFIG_IDF_TARGET_ESP32 esp_rom_uart_tx_wait_idle(i); #else - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + if (periph_ll_uart_enabled(i)) { esp_rom_uart_tx_wait_idle(i); } #endif @@ -437,14 +439,15 @@ static void IRAM_ATTR flush_uarts(void) static uint32_t s_suspended_uarts_bmap = 0; /** - * Suspend enabled uarts and return suspended uarts bit map + * Suspend enabled uarts and return suspended uarts bit map. + * Must be called from critical sections. */ -static IRAM_ATTR void suspend_uarts(void) +FORCE_INLINE_ATTR void suspend_uarts(void) { s_suspended_uarts_bmap = 0; for (int i = 0; i < SOC_UART_HP_NUM; ++i) { #ifndef CONFIG_IDF_TARGET_ESP32 - if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + if (!periph_ll_uart_enabled(i)) { continue; } #endif @@ -461,7 +464,8 @@ static IRAM_ATTR void suspend_uarts(void) } } -static void IRAM_ATTR resume_uarts(void) +// Must be called from critical sections +FORCE_INLINE_ATTR void resume_uarts(void) { for (int i = 0; i < SOC_UART_HP_NUM; ++i) { if (s_suspended_uarts_bmap & 0x1) { @@ -487,7 +491,7 @@ static void IRAM_ATTR resume_uarts(void) completion time has exceeded the wakeup time, we should abandon the flush, skip the sleep and return ESP_ERR_SLEEP_REJECT. */ -static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration) +FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration) { bool should_skip_sleep = false; #if !SOC_PM_SUPPORT_TOP_PD @@ -513,7 +517,7 @@ static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration) /** * These save-restore workaround should be moved to lower layer */ -inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) +FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) { if (deep_sleep){ for (int n = 0; n < MAX_DSLP_HOOKS; n++) { @@ -548,7 +552,7 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) /** * These save-restore workaround should be moved to lower layer */ -inline static void IRAM_ATTR misc_modules_wake_prepare(void) +FORCE_INLINE_ATTR void misc_modules_wake_prepare(void) { #if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG sleep_retention_do_system_retention(false); @@ -746,7 +750,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m In order to avoid the leakage of the SPI cs pin, hold it here */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet - if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { + if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { /* Cache Suspend 1: will wait cache idle in cache suspend, also means SPI bus IDLE, then we can hold SPI CS pin safely*/ suspend_cache(); gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM); @@ -769,7 +773,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m /* Unhold the SPI CS pin */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet - if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { + if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); /* Cache Resume 1: Resume cache for continue running*/ resume_cache(); @@ -949,7 +953,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, * x | 1 | pd flash with relaxed conditions(force_pd) * 1 | 0 | pd flash with strict conditions(safe_pd) */ -static inline bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration) +FORCE_INLINE_ATTR bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration) { bool force_pd = !(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration); bool safe_pd = (s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration); @@ -1702,7 +1706,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_ * the XTAL clock control of some chips(esp32c6/esp32h2) depends on the top domain. */ #if SOC_PM_SUPPORT_TOP_PD -static inline bool top_domain_pd_allowed(void) { +FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { return (cpu_domain_pd_allowed() && \ clock_domain_pd_allowed() && \ peripheral_domain_pd_allowed() && \ @@ -1794,7 +1798,7 @@ static uint32_t get_power_down_flags(void) s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF; #endif - const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; + const __attribute__((unused)) char *option_str[] = {DRAM_STR("OFF"), DRAM_STR("ON"), DRAM_STR("AUTO(OFF)") /* Auto works as OFF */}; /* This function is called from a critical section, log with ESP_EARLY_LOGD. */ #if SOC_PM_SUPPORT_RTC_PERIPH_PD ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option]); diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 8f472d84d8..cf11270f2e 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -236,7 +236,7 @@ error: return err; } -bool IRAM_ATTR peripheral_domain_pd_allowed(void) +bool peripheral_domain_pd_allowed(void) { const uint32_t modules = sleep_retention_get_modules(); const uint32_t mask = (const uint32_t) ( diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index 4541fb3347..c48533368d 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -51,8 +51,8 @@ menu "Power Management" bool "Put lightsleep related codes in internal RAM" depends on FREERTOS_USE_TICKLESS_IDLE help - If enabled, about 1.8KB of lightsleep related source code would be in IRAM and chip would sleep - longer for 760us at most each time. + If enabled, about 2.1KB of lightsleep related source code would be in IRAM and chip would sleep + longer for 310us at 160MHz CPU frequency most each time. This feature is intended to be used when lower power consumption is needed while there is enough place in IRAM to place source code. @@ -60,8 +60,8 @@ menu "Power Management" bool "Put RTOS IDLE related codes in internal RAM" depends on FREERTOS_USE_TICKLESS_IDLE help - If enabled, about 260B of RTOS_IDLE related source code would be in IRAM and chip would sleep - longer for 40us at most each time. + If enabled, about 180Bytes of RTOS_IDLE related source code would be in IRAM and chip would sleep + longer for 20us at 160MHz CPU frequency most each time. This feature is intended to be used when lower power consumption is needed while there is enough place in IRAM to place source code. diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index 12d9282a40..40307535b8 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -5,6 +5,9 @@ entries: pm_impl:esp_pm_impl_idle_hook (noflash) pm_impl:esp_pm_impl_waiti (noflash) + if PM_SLP_IRAM_OPT = y: + pm_impl:esp_pm_impl_get_cpu_freq (noflash) + [mapping:esp_hw_support_pm] archive: libesp_hw_support.a entries: @@ -16,12 +19,24 @@ entries: esp_clk:esp_clk_slowclk_cal_set (noflash) esp_clk:esp_clk_slowclk_cal_get (noflash) esp_clk:esp_rtc_get_time_us (noflash) + esp_clk:esp_clk_private_lock (noflash) + esp_clk:esp_clk_private_unlock (noflash) + if SOC_RTC_MEM_SUPPORTED = y: + esp_clk:calc_checksum (noflash) + if SOC_SYSTIMER_SUPPORTED = y: + systimer (noflash) if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: sleep_gpio:gpio_sleep_mode_config_apply (noflash) if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (SOC_PM_SUPPORT_CPU_PD = y || SOC_PM_SUPPORT_TAGMEM_PD = y): sleep_cpu:sleep_enable_cpu_retention (noflash) if SOC_PM_SUPPORT_CPU_PD = y: sleep_cpu:cpu_domain_pd_allowed (noflash) + if SOC_PM_SUPPORT_TOP_PD = y: + sleep_clock:clock_domain_pd_allowed (noflash) + sleep_system_peripheral:peripheral_domain_pd_allowed (noflash) + sleep_modem:modem_domain_pd_allowed (noflash) + sleep_modem:periph_inform_out_light_sleep_overhead (noflash) + sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash) [mapping:esp_system_pm] archive: libesp_system.a @@ -48,10 +63,12 @@ entries: esp_timer_impl_lac:esp_timer_impl_lock (noflash) esp_timer_impl_lac:esp_timer_impl_unlock (noflash) esp_timer_impl_lac:esp_timer_impl_advance (noflash) + esp_timer_impl_lac:esp_timer_impl_set (noflash) elif ESP_TIMER_IMPL_SYSTIMER = y: esp_timer_impl_systimer:esp_timer_impl_lock (noflash) esp_timer_impl_systimer:esp_timer_impl_unlock (noflash) esp_timer_impl_systimer:esp_timer_impl_advance (noflash) + esp_timer_impl_systimer:esp_timer_impl_set (noflash) [mapping:newlib_pm] archive: libnewlib.a diff --git a/components/hal/esp32c6/modem_clock_hal.c b/components/hal/esp32c6/modem_clock_hal.c index 553c7cbfac..e89e19c7fe 100644 --- a/components/hal/esp32c6/modem_clock_hal.c +++ b/components/hal/esp32c6/modem_clock_hal.c @@ -19,7 +19,7 @@ typedef enum { MODEM_CLOCK_EXT32K_CODE = 2 } modem_clock_32k_clk_src_code_t; -void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap) +void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap) { HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); switch (domain) @@ -101,7 +101,7 @@ uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t * return bitmap; } -void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) +void IRAM_ATTR modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) { if (enable) { modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable); diff --git a/components/hal/esp32c6/pmu_hal.c b/components/hal/esp32c6/pmu_hal.c index 4997eacce6..7e4a73177b 100644 --- a/components/hal/esp32c6/pmu_hal.c +++ b/components/hal/esp32c6/pmu_hal.c @@ -11,26 +11,26 @@ #include "hal/pmu_hal.h" #include "hal/pmu_types.h" -void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); return power_supply_wait_cycle + power_up_wait_cycle; } -void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); diff --git a/components/hal/esp32h2/modem_clock_hal.c b/components/hal/esp32h2/modem_clock_hal.c index eb77e7b45b..8534cd4a86 100644 --- a/components/hal/esp32h2/modem_clock_hal.c +++ b/components/hal/esp32h2/modem_clock_hal.c @@ -19,7 +19,7 @@ typedef enum { MODEM_CLOCK_EXT32K_CODE = 2 } modem_clock_32k_clk_src_code_t; -void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) +void IRAM_ATTR modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) { modem_lpcon_ll_enable_fe_mem_clock(hal->lpcon_dev, enable); modem_syscon_ll_enable_fe_sdm_clock(hal->syscon_dev, enable); diff --git a/components/hal/esp32h2/pmu_hal.c b/components/hal/esp32h2/pmu_hal.c index 9da9eaed80..a10477bfe1 100644 --- a/components/hal/esp32h2/pmu_hal.c +++ b/components/hal/esp32h2/pmu_hal.c @@ -11,26 +11,26 @@ #include "hal/pmu_hal.h" #include "hal/pmu_types.h" -void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); return power_supply_wait_cycle + power_up_wait_cycle; } -void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 871380d91a..9496f0d597 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -934,7 +934,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_force_xoff(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) { REG_CLR_BIT(UART_FLOW_CONF_REG(uart_num), UART_FORCE_XON); REG_SET_BIT(UART_FLOW_CONF_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); diff --git a/components/hal/linker.lf b/components/hal/linker.lf index 8474d30d3a..d6907d741b 100644 --- a/components/hal/linker.lf +++ b/components/hal/linker.lf @@ -50,3 +50,5 @@ entries: adc_hal: adc_hal_check_event (noflash) adc_hal: adc_hal_digi_clr_intr (noflash) adc_hal: adc_hal_get_desc_addr (noflash) + if SOC_PMU_SUPPORTED = y: + pmu_hal (noflash) From 797efb1dd3c5382bc0ed4d7e1e8141341b8e41b6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 7 Jun 2023 19:51:06 +0800 Subject: [PATCH 6/6] ci: add pd_vddsdio in lightsleep UT tests - Add pd_vddsdio in lightsleep UT tests to ensure proper functionality --- components/driver/test_apps/gpio/sdkconfig.ci.iram_safe | 1 + .../driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe | 1 + components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe | 1 + .../driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe | 1 + components/driver/test_apps/mcpwm/sdkconfig.ci.iram_safe | 1 + components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe | 1 + components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py | 1 + components/esp_pm/test_apps/esp_pm/sdkconfig.ci.slp_iram_opt | 4 ++++ .../esp_system_unity_tests/pytest_esp_system_unity_tests.py | 1 + .../test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio | 3 +++ components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special | 1 + tools/test_apps/build_system/ldgen_test/main/linker.lf | 3 ++- 12 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 components/esp_pm/test_apps/esp_pm/sdkconfig.ci.slp_iram_opt create mode 100644 components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio diff --git a/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe b/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe index fd46a672d2..8d43b77909 100644 --- a/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe @@ -5,5 +5,6 @@ CONFIG_COMPILER_OPTIMIZATION_NONE=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe b/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe index 7e63e6d096..1742ded1a1 100644 --- a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe @@ -5,5 +5,6 @@ CONFIG_COMPILER_OPTIMIZATION_NONE=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe b/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe index b53844d9c0..1d300d8f3d 100644 --- a/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe @@ -6,3 +6,4 @@ CONFIG_COMPILER_OPTIMIZATION_NONE=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe index c679a19a27..0128347673 100644 --- a/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe @@ -3,5 +3,6 @@ CONFIG_I2S_ISR_IRAM_SAFE=y CONFIG_COMPILER_OPTIMIZATION_NONE=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # place non-ISR FreeRTOS functions in Flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y diff --git a/components/driver/test_apps/mcpwm/sdkconfig.ci.iram_safe b/components/driver/test_apps/mcpwm/sdkconfig.ci.iram_safe index 4d8a456b73..48d7bef34a 100644 --- a/components/driver/test_apps/mcpwm/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/mcpwm/sdkconfig.ci.iram_safe @@ -5,5 +5,6 @@ CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y CONFIG_COMPILER_OPTIMIZATION_NONE=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # place non-ISR FreeRTOS functions in Flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe b/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe index 8725c6ff2e..9f499a5f92 100644 --- a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe @@ -5,5 +5,6 @@ CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y CONFIG_COMPILER_OPTIMIZATION_NONE=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # place non-ISR FreeRTOS functions in Flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y 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 3e6d410793..9c241c1971 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 @@ -9,6 +9,7 @@ from pytest_embedded import Dut @pytest.mark.supported_targets @pytest.mark.parametrize('config', [ 'default', + 'slp_iram_opt', 'limits', 'options', ], indirect=True) diff --git a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.slp_iram_opt b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.slp_iram_opt new file mode 100644 index 0000000000..ebffd40c4b --- /dev/null +++ b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.slp_iram_opt @@ -0,0 +1,4 @@ +CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_PM_RTOS_IDLE_OPT=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y diff --git a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py index 4afa08c403..4d094eb313 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py +++ b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py @@ -10,6 +10,7 @@ from pytest_embedded import Dut 'config', [ pytest.param('default', marks=[pytest.mark.supported_targets]), + pytest.param('pd_vddsdio', marks=[pytest.mark.supported_targets]), pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3]), pytest.param('single_core_esp32', marks=[pytest.mark.esp32]), ] diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio new file mode 100644 index 0000000000..42890166e9 --- /dev/null +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio @@ -0,0 +1,3 @@ +CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special index 250b5921a6..2ce9a5bff6 100644 --- a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special @@ -2,4 +2,5 @@ CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_COMPILER_OPTIMIZATION_NONE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_COMPILER_DUMP_RTL_FILES=y diff --git a/tools/test_apps/build_system/ldgen_test/main/linker.lf b/tools/test_apps/build_system/ldgen_test/main/linker.lf index ca51283c1b..63150db29d 100644 --- a/tools/test_apps/build_system/ldgen_test/main/linker.lf +++ b/tools/test_apps/build_system/ldgen_test/main/linker.lf @@ -5,4 +5,5 @@ entries: src1 (default) src1:func1 (noflash); text->iram0_text KEEP() ALIGN(9) ALIGN(12, post) SURROUND(sym1) - src1:func2 (rtc) + if SOC_RTC_MEM_SUPPORTED = y: + src1:func2 (rtc)