Merge branch 'bugfix/esp_idf_s3_deepsleep_dead_v6.0' into 'release/v6.0'

fix(hal): fix the issue of dual-core contention for RTC_CNTL regs(v6.0)

See merge request espressif/esp-idf!46180
This commit is contained in:
Jiang Jiang Jian
2026-03-20 10:15:14 +08:00
21 changed files with 255 additions and 54 deletions
+10
View File
@@ -69,6 +69,8 @@
#define BT_LOG_TAG "BLE_INIT" #define BT_LOG_TAG "BLE_INIT"
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#define BTDM_INIT_PERIOD (5000) /* ms */ #define BTDM_INIT_PERIOD (5000) /* ms */
/* Low Power Clock Selection */ /* Low Power Clock Selection */
@@ -804,8 +806,10 @@ void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void)
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_BT_PD #if SOC_PM_SUPPORT_BT_PD
// Bluetooth module power down // Bluetooth module power down
RTC_CNTL_ATOMIC() {
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
}
#endif #endif
esp_mac_bb_power_down(); esp_mac_bb_power_down();
#endif #endif
@@ -816,8 +820,10 @@ void IRAM_ATTR btdm_hw_mac_power_up_wrapper(void)
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_BT_PD #if SOC_PM_SUPPORT_BT_PD
// Bluetooth module power up // Bluetooth module power up
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
}
#endif #endif
esp_mac_bb_power_up(); esp_mac_bb_power_up();
#endif #endif
@@ -834,8 +840,10 @@ static inline void esp_bt_power_domain_on(void)
{ {
// Bluetooth module power up // Bluetooth module power up
#if SOC_PM_SUPPORT_BT_PD #if SOC_PM_SUPPORT_BT_PD
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
}
#endif #endif
esp_wifi_bt_power_domain_on(); esp_wifi_bt_power_domain_on();
} }
@@ -844,8 +852,10 @@ static inline void esp_bt_power_domain_off(void)
{ {
// Bluetooth module power down // Bluetooth module power down
#if SOC_PM_SUPPORT_BT_PD #if SOC_PM_SUPPORT_BT_PD
RTC_CNTL_ATOMIC() {
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
}
#endif #endif
esp_wifi_bt_power_domain_off(); esp_wifi_bt_power_domain_off();
} }
+15
View File
@@ -22,6 +22,7 @@
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "esp_private/esp_gpio_reserve.h" #include "esp_private/esp_gpio_reserve.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#if (SOC_RTCIO_PIN_COUNT > 0) #if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h" #include "hal/rtc_io_hal.h"
@@ -40,6 +41,12 @@ static const char *GPIO_TAG = "gpio";
#define GPIO_RTCIO_ARE_INDEPENDENT 1 #define GPIO_RTCIO_ARE_INDEPENDENT 1
#endif #endif
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
typedef struct { typedef struct {
gpio_isr_t fn; /*!< isr function */ gpio_isr_t fn; /*!< isr function */
void *args; /*!< isr function args */ void *args; /*!< isr function args */
@@ -781,14 +788,18 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
void gpio_deep_sleep_hold_en(void) void gpio_deep_sleep_hold_en(void)
{ {
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
RTC_CNTL_ATOMIC() {
gpio_hal_deep_sleep_hold_en(gpio_context.gpio_hal); gpio_hal_deep_sleep_hold_en(gpio_context.gpio_hal);
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
} }
void gpio_deep_sleep_hold_dis(void) void gpio_deep_sleep_hold_dis(void)
{ {
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
RTC_CNTL_ATOMIC() {
gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal); gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
} }
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP #endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
@@ -800,7 +811,9 @@ esp_err_t IRAM_ATTR gpio_force_hold_all()
rtc_gpio_force_hold_en_all(); rtc_gpio_force_hold_en_all();
#endif #endif
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
RTC_CNTL_ATOMIC() {
gpio_hal_force_hold_all(); gpio_hal_force_hold_all();
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -808,7 +821,9 @@ esp_err_t IRAM_ATTR gpio_force_hold_all()
esp_err_t IRAM_ATTR gpio_force_unhold_all() esp_err_t IRAM_ATTR gpio_force_unhold_all()
{ {
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
RTC_CNTL_ATOMIC() {
gpio_hal_force_unhold_all(); gpio_hal_force_unhold_all();
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
#if SOC_RTCIO_HOLD_SUPPORTED #if SOC_RTCIO_HOLD_SUPPORTED
rtc_gpio_force_hold_dis_all(); rtc_gpio_force_hold_dis_all();
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -578,22 +578,32 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_en(__VA_ARGS__)
/** /**
* @brief Disable all digital gpio pad hold function during Deep-sleep. * @brief Disable all digital gpio pad hold function during Deep-sleep.
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_dis(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_dis(__VA_ARGS__)
/** /**
* @brief Get deep sleep hold status * @brief Get deep sleep hold status
* *
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -388,22 +388,32 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_en(__VA_ARGS__)
/** /**
* @brief Disable all digital gpio pad hold function during Deep-sleep. * @brief Disable all digital gpio pad hold function during Deep-sleep.
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_dis(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_dis(__VA_ARGS__)
/** /**
* @brief Get deep sleep hold status * @brief Get deep sleep hold status
* *
@@ -547,18 +557,23 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_hold_all(void) static inline void _gpio_ll_force_hold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, RTC_CNTL_PWC_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_hold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_hold_all(__VA_ARGS__)
/** /**
* @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode. * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_unhold_all(void) static inline void _gpio_ll_force_unhold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
@@ -566,6 +581,11 @@ static inline void gpio_ll_force_unhold_all(void)
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, RTC_CNTL_PWC_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_unhold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_unhold_all(__VA_ARGS__)
/** /**
* @brief Enable GPIO pin used for wakeup from sleep. * @brief Enable GPIO pin used for wakeup from sleep.
* *
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -385,22 +385,32 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_en(__VA_ARGS__)
/** /**
* @brief Disable all digital gpio pad hold function during Deep-sleep. * @brief Disable all digital gpio pad hold function during Deep-sleep.
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_dis(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_dis(__VA_ARGS__)
/** /**
* @brief Get deep sleep hold status * @brief Get deep sleep hold status
* *
@@ -544,18 +554,23 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_hold_all(void) static inline void _gpio_ll_force_hold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, RTC_CNTL_PWC_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_hold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_hold_all(__VA_ARGS__)
/** /**
* @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode. * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_unhold_all(void) static inline void _gpio_ll_force_unhold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
@@ -563,6 +578,11 @@ static inline void gpio_ll_force_unhold_all(void)
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, RTC_CNTL_PWC_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_unhold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_unhold_all(__VA_ARGS__)
/** /**
* @brief Enable GPIO pin used for wakeup from sleep. * @brief Enable GPIO pin used for wakeup from sleep.
* *
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -406,22 +406,32 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_en(__VA_ARGS__)
/** /**
* @brief Disable all digital gpio pad hold function during Deep-sleep. * @brief Disable all digital gpio pad hold function during Deep-sleep.
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_dis(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_dis(__VA_ARGS__)
/** /**
* @brief Get deep sleep hold status * @brief Get deep sleep hold status
* *
@@ -557,23 +567,33 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
* @brief Force hold digital gpio pad. * @brief Force hold digital gpio pad.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_hold_all(void) static inline void _gpio_ll_force_hold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_hold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_hold_all(__VA_ARGS__)
/** /**
* @brief Force unhold digital gpio pad. * @brief Force unhold digital gpio pad.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode. * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_unhold_all(void) static inline void _gpio_ll_force_unhold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_unhold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_unhold_all(__VA_ARGS__)
/** /**
* @brief Enable GPIO pin used for wakeup from sleep. * @brief Enable GPIO pin used for wakeup from sleep.
* *
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -407,22 +407,32 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_en(__VA_ARGS__)
/** /**
* @brief Disable all digital gpio pad hold function during Deep-sleep. * @brief Disable all digital gpio pad hold function during Deep-sleep.
* *
* @param hw Peripheral GPIO hardware instance address. * @param hw Peripheral GPIO hardware instance address.
*/ */
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) static inline void _gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_deep_sleep_hold_dis(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_deep_sleep_hold_dis(__VA_ARGS__)
/** /**
* @brief Get deep sleep hold status * @brief Get deep sleep hold status
* *
@@ -558,23 +568,33 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
* @brief Force hold digital gpio pad. * @brief Force hold digital gpio pad.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_hold_all(void) static inline void _gpio_ll_force_hold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_hold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_hold_all(__VA_ARGS__)
/** /**
* @brief Force unhold digital gpio pad. * @brief Force unhold digital gpio pad.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode. * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/ */
static inline void gpio_ll_force_unhold_all(void) static inline void _gpio_ll_force_unhold_all(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
} }
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
/// When operating RTC_CNTL_DIG_ISO_REG, PERIPH_RCC_ATOMIC() must be used to ensure atomicity.
#define gpio_ll_force_unhold_all(...) (void)__DECLARE_RCC_ATOMIC_ENV; _gpio_ll_force_unhold_all(__VA_ARGS__)
/** /**
* @brief Enable GPIO pin used for wakeup from sleep. * @brief Enable GPIO pin used for wakeup from sleep.
* *
+12 -1
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2016-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -19,8 +19,15 @@
#include "sys/lock.h" #include "sys/lock.h"
#include "esp_private/rtc_ctrl.h" #include "esp_private/rtc_ctrl.h"
#include "esp_private/critical_section.h" #include "esp_private/critical_section.h"
#include "esp_private/periph_ctrl.h"
#include "esp_attr.h" #include "esp_attr.h"
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
#ifndef NDEBUG #ifndef NDEBUG
// Enable built-in checks in queue.h in debug builds // Enable built-in checks in queue.h in debug builds
@@ -188,9 +195,11 @@ IRAM_ATTR void rtc_isr_noniram_disable(uint32_t cpu)
{ {
#if SOC_LP_PERIPH_SHARE_INTERRUPT // TODO: IDF-8008 #if SOC_LP_PERIPH_SHARE_INTERRUPT // TODO: IDF-8008
if (rtc_isr_cpu == cpu) { if (rtc_isr_cpu == cpu) {
RTC_CNTL_ATOMIC() {
rtc_intr_enabled |= RTCCNTL.int_ena.val; rtc_intr_enabled |= RTCCNTL.int_ena.val;
RTCCNTL.int_ena.val &= rtc_intr_cache; RTCCNTL.int_ena.val &= rtc_intr_cache;
} }
}
#endif #endif
} }
@@ -198,8 +207,10 @@ IRAM_ATTR void rtc_isr_noniram_enable(uint32_t cpu)
{ {
#if SOC_LP_PERIPH_SHARE_INTERRUPT // TODO: IDF-8008 #if SOC_LP_PERIPH_SHARE_INTERRUPT // TODO: IDF-8008
if (rtc_isr_cpu == cpu) { if (rtc_isr_cpu == cpu) {
RTC_CNTL_ATOMIC() {
RTCCNTL.int_ena.val = rtc_intr_enabled; RTCCNTL.int_ena.val = rtc_intr_enabled;
rtc_intr_enabled = 0; rtc_intr_enabled = 0;
} }
}
#endif #endif
} }
+11
View File
@@ -109,6 +109,11 @@ static uint32_t* s_phy_digital_regs_mem = NULL;
static uint8_t s_phy_modem_init_ref = 0; static uint8_t s_phy_modem_init_ref = 0;
#endif #endif
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN #if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN
#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN_EMBED #if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN_EMBED
@@ -441,7 +446,9 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void)
#if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667 #if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock); _lock_acquire(&s_wifi_bt_pd_controller.lock);
if (s_wifi_bt_pd_controller.count++ == 0) { if (s_wifi_bt_pd_controller.count++ == 0) {
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
}
esp_rom_delay_us(10); esp_rom_delay_us(10);
wifi_bt_common_module_enable(); wifi_bt_common_module_enable();
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
@@ -452,7 +459,9 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void)
SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU);
CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU);
#endif #endif
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO);
}
wifi_bt_common_module_disable(); wifi_bt_common_module_disable();
} }
_lock_release(&s_wifi_bt_pd_controller.lock); _lock_release(&s_wifi_bt_pd_controller.lock);
@@ -466,9 +475,11 @@ void esp_wifi_bt_power_domain_off(void)
#if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667 #if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock); _lock_acquire(&s_wifi_bt_pd_controller.lock);
if (--s_wifi_bt_pd_controller.count == 0) { if (--s_wifi_bt_pd_controller.count == 0) {
RTC_CNTL_ATOMIC() {
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
} }
}
_lock_release(&s_wifi_bt_pd_controller.lock); _lock_release(&s_wifi_bt_pd_controller.lock);
#endif // SOC_PM_MODEM_PD_BY_SW #endif // SOC_PM_MODEM_PD_BY_SW
#endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD #endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
@@ -495,6 +495,10 @@ config SOC_RTCIO_WAKE_SUPPORTED
bool bool
default y default y
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_SPI_HD_BOTH_INOUT_SUPPORTED config SOC_SPI_HD_BOTH_INOUT_SUPPORTED
bool bool
default y default y
@@ -250,6 +250,10 @@
#define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_HOLD_SUPPORTED 1
#define SOC_RTCIO_WAKE_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1
/* RTC_CNTL registers on this SoC are not atomic and require software protection
* (e.g., spinlocks) when accessed from multiple cores or threads. */
#define SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS 1
/*-------------------------- SPI CAPS ----------------------------------------*/ /*-------------------------- SPI CAPS ----------------------------------------*/
#define SOC_SPI_HD_BOTH_INOUT_SUPPORTED 1 //Support enabling MOSI and MISO phases together under Halfduplex mode #define SOC_SPI_HD_BOTH_INOUT_SUPPORTED 1 //Support enabling MOSI and MISO phases together under Halfduplex mode
#define SOC_SPI_AS_CS_SUPPORTED 1 //Support to toggle the CS while the clock toggles #define SOC_SPI_AS_CS_SUPPORTED 1 //Support to toggle the CS while the clock toggles
@@ -407,6 +407,10 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int int
default 108 default 108
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_RTCIO_PIN_COUNT config SOC_RTCIO_PIN_COUNT
int int
default 0 default 0
@@ -185,6 +185,10 @@
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) #define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
/* RTC_CNTL registers on this SoC are not atomic and require software protection
* (e.g., spinlocks) when accessed from multiple cores or threads. */
#define SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS 1
/*-------------------------- RTCIO CAPS --------------------------------------*/ /*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated RTCIO subsystem on ESP32-C2. RTC functions are still supported /* No dedicated RTCIO subsystem on ESP32-C2. RTC functions are still supported
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */
@@ -559,6 +559,10 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int int
default 108 default 108
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
bool bool
default y default y
@@ -244,6 +244,10 @@
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) #define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
/* RTC_CNTL registers on this SoC are not atomic and require software protection
* (e.g., spinlocks) when accessed from multiple cores or threads. */
#define SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS 1
#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1 #define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1
#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1 #define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1
@@ -423,6 +423,10 @@ config SOC_GPIO_CLOCKOUT_CHANNEL_NUM
int int
default 3 default 3
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_DEDIC_GPIO_HAS_INTERRUPT config SOC_DEDIC_GPIO_HAS_INTERRUPT
bool bool
default y default y
@@ -198,6 +198,10 @@
#define SOC_GPIO_CLOCKOUT_BY_IO_MUX (1) #define SOC_GPIO_CLOCKOUT_BY_IO_MUX (1)
#define SOC_GPIO_CLOCKOUT_CHANNEL_NUM (3) #define SOC_GPIO_CLOCKOUT_CHANNEL_NUM (3)
/* RTC_CNTL registers on this SoC are not atomic and require software protection
* (e.g., spinlocks) when accessed from multiple cores or threads. */
#define SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS 1
/*-------------------------- Dedicated GPIO CAPS ---------------------------------------*/ /*-------------------------- Dedicated GPIO CAPS ---------------------------------------*/
#define SOC_DEDIC_GPIO_HAS_INTERRUPT (1) /*!< Dedicated GPIO has its own interrupt source */ #define SOC_DEDIC_GPIO_HAS_INTERRUPT (1) /*!< Dedicated GPIO has its own interrupt source */
@@ -635,6 +635,10 @@ config SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH
int int
default 128 default 128
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_RTCIO_PIN_COUNT config SOC_RTCIO_PIN_COUNT
int int
default 22 default 22
@@ -264,6 +264,10 @@
#define SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH (128) #define SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH (128)
#define SOC_RTC_CNTL_TAGMEM_PD_DMA_ADDR_ALIGN (SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH >> 3) #define SOC_RTC_CNTL_TAGMEM_PD_DMA_ADDR_ALIGN (SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH >> 3)
/* RTC_CNTL registers on this SoC are not atomic and require software protection
* (e.g., spinlocks) when accessed from multiple cores or threads. */
#define SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS 1
/*-------------------------- RTCIO CAPS --------------------------------------*/ /*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 22 #define SOC_RTCIO_PIN_COUNT 22
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, #define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature,
+14 -1
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -30,6 +30,13 @@
#include "esp_check.h" #include "esp_check.h"
#include "esp_private/rtc_ctrl.h" #include "esp_private/rtc_ctrl.h"
#include "esp_private/periph_ctrl.h"
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
typedef struct { typedef struct {
uint32_t magic; uint32_t magic;
@@ -46,7 +53,10 @@ static const char* TAG = "ulp";
esp_err_t ulp_isr_register(intr_handler_t fn, void *arg) esp_err_t ulp_isr_register(intr_handler_t fn, void *arg)
{ {
ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL"); ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL");
/* Enable the interrupt bit atomically to avoid race condition with other code accessing RTC_CNTL_INT_ENA_REG */
RTC_CNTL_ATOMIC() {
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M); REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
}
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
return rtc_isr_register(fn, arg, RTC_CNTL_SAR_INT_ST_M, 0); return rtc_isr_register(fn, arg, RTC_CNTL_SAR_INT_ST_M, 0);
#else #else
@@ -57,7 +67,10 @@ esp_err_t ulp_isr_register(intr_handler_t fn, void *arg)
esp_err_t ulp_isr_deregister(intr_handler_t fn, void *arg) esp_err_t ulp_isr_deregister(intr_handler_t fn, void *arg)
{ {
ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL"); ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL");
/* Disable the interrupt bit atomically to avoid race condition with other code accessing RTC_CNTL_INT_ENA_REG */
RTC_CNTL_ATOMIC() {
REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M); REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
}
return rtc_isr_deregister(fn, arg); return rtc_isr_deregister(fn, arg);
} }
+16 -5
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -22,6 +22,13 @@
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_check.h" #include "esp_check.h"
#include "esp_private/rtc_ctrl.h" #include "esp_private/rtc_ctrl.h"
#include "esp_private/periph_ctrl.h"
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
__attribute__((unused)) static const char* TAG = "ulp-riscv"; __attribute__((unused)) static const char* TAG = "ulp-riscv";
@@ -44,8 +51,10 @@ esp_err_t ulp_riscv_isr_register(intr_handler_t fn, void *arg, uint32_t mask)
/* Register the RTC ISR */ /* Register the RTC ISR */
ESP_RETURN_ON_ERROR(rtc_isr_register(fn, arg, mask, 0), TAG, "rtc_isr_register() failed"); ESP_RETURN_ON_ERROR(rtc_isr_register(fn, arg, mask, 0), TAG, "rtc_isr_register() failed");
/* Enable the interrupt bits */ /* Enable the interrupt bits atomically to avoid race condition with other code accessing RTC_CNTL_INT_ENA_REG */
RTC_CNTL_ATOMIC() {
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask); SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask);
}
return ESP_OK; return ESP_OK;
} }
@@ -64,8 +73,10 @@ esp_err_t ulp_riscv_isr_deregister(intr_handler_t fn, void *arg, uint32_t mask)
/* Make sure we disable only the ULP interrupt bits */ /* Make sure we disable only the ULP interrupt bits */
mask &= (RTC_CNTL_COCPU_INT_ST_M | RTC_CNTL_COCPU_TRAP_INT_ST_M); mask &= (RTC_CNTL_COCPU_INT_ST_M | RTC_CNTL_COCPU_TRAP_INT_ST_M);
/* Disable the interrupt bits */ /* Disable the interrupt bits atomically to avoid race condition with other code accessing RTC_CNTL_INT_ENA_REG */
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask); CLEAR_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask);
}
/* Deregister the RTC ISR */ /* Deregister the RTC ISR */
ESP_RETURN_ON_ERROR(rtc_isr_deregister(fn, arg), TAG, "rtc_isr_deregister() failed"); ESP_RETURN_ON_ERROR(rtc_isr_deregister(fn, arg), TAG, "rtc_isr_deregister() failed");
@@ -103,7 +114,7 @@ esp_err_t ulp_riscv_config_and_run(ulp_riscv_cfg_t* cfg)
/* Reset COCPU when power on. */ /* Reset COCPU when power on. */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
/* The coprocessor cpu trap signal doesnt have a stable reset value, /* The coprocessor cpu trap signal doesn't have a stable reset value,
force ULP-RISC-V clock on to stop RTC_COCPU_TRAP_TRIG_EN from waking the CPU*/ force ULP-RISC-V clock on to stop RTC_COCPU_TRAP_TRIG_EN from waking the CPU*/
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO); SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO);
@@ -123,7 +134,7 @@ esp_err_t ulp_riscv_config_and_run(ulp_riscv_cfg_t* cfg)
/* Reset COCPU when power on. */ /* Reset COCPU when power on. */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
/* The coprocessor cpu trap signal doesnt have a stable reset value, /* The coprocessor cpu trap signal doesn't have a stable reset value,
force ULP-RISC-V clock on to stop RTC_COCPU_TRAP_TRIG_EN from waking the CPU*/ force ULP-RISC-V clock on to stop RTC_COCPU_TRAP_TRIG_EN from waking the CPU*/
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO); SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO);