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

This commit is contained in:
hebinglin
2025-09-01 20:29:48 +08:00
parent ce0597161e
commit baeabe48c3
21 changed files with 254 additions and 53 deletions
+19 -9
View File
@@ -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
*/
@@ -69,6 +69,8 @@
#define BT_LOG_TAG "BLE_INIT"
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#define BTDM_INIT_PERIOD (5000) /* ms */
/* Low Power Clock Selection */
@@ -801,8 +803,10 @@ void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void)
#if CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_BT_PD
// Bluetooth module power down
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);
RTC_CNTL_ATOMIC() {
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);
}
#endif
esp_mac_bb_power_down();
#endif
@@ -813,8 +817,10 @@ void IRAM_ATTR btdm_hw_mac_power_up_wrapper(void)
#if CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_BT_PD
// Bluetooth module power up
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);
RTC_CNTL_ATOMIC() {
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);
}
#endif
esp_mac_bb_power_up();
#endif
@@ -831,8 +837,10 @@ static inline void esp_bt_power_domain_on(void)
{
// Bluetooth module power up
#if SOC_PM_SUPPORT_BT_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);
RTC_CNTL_ATOMIC() {
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);
}
#endif
esp_wifi_bt_power_domain_on();
}
@@ -841,8 +849,10 @@ static inline void esp_bt_power_domain_off(void)
{
// Bluetooth module power down
#if SOC_PM_SUPPORT_BT_PD
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);
RTC_CNTL_ATOMIC() {
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);
}
#endif
esp_wifi_bt_power_domain_off();
}
+19 -4
View File
@@ -22,6 +22,7 @@
#include "hal/gpio_hal.h"
#include "esp_private/esp_gpio_reserve.h"
#include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h"
@@ -40,6 +41,12 @@ static const char *GPIO_TAG = "gpio";
#define GPIO_RTCIO_ARE_INDEPENDENT 1
#endif
#if SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
#define RTC_CNTL_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define RTC_CNTL_ATOMIC()
#endif
typedef struct {
gpio_isr_t fn; /*!< isr function */
void *args; /*!< isr function args */
@@ -784,14 +791,18 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
void gpio_deep_sleep_hold_en(void)
{
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
gpio_hal_deep_sleep_hold_en(gpio_context.gpio_hal);
RTC_CNTL_ATOMIC() {
gpio_hal_deep_sleep_hold_en(gpio_context.gpio_hal);
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
}
void gpio_deep_sleep_hold_dis(void)
{
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
RTC_CNTL_ATOMIC() {
gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
}
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
@@ -803,7 +814,9 @@ esp_err_t IRAM_ATTR gpio_force_hold_all()
rtc_gpio_force_hold_en_all();
#endif
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
gpio_hal_force_hold_all();
RTC_CNTL_ATOMIC() {
gpio_hal_force_hold_all();
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
return ESP_OK;
}
@@ -811,7 +824,9 @@ esp_err_t IRAM_ATTR gpio_force_hold_all()
esp_err_t IRAM_ATTR gpio_force_unhold_all()
{
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
gpio_hal_force_unhold_all();
RTC_CNTL_ATOMIC() {
gpio_hal_force_unhold_all();
}
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
#if SOC_RTCIO_HOLD_SUPPORTED
rtc_gpio_force_hold_dis_all();
@@ -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.
*/
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);
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.
*
* @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);
}
/// 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
*
@@ -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
*/
@@ -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.
*/
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);
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.
*
* @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);
}
/// 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
*
@@ -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.
* @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);
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);
}
/// 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.
* @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);
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);
}
/// 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.
*
@@ -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
*/
@@ -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.
*/
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);
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.
*
* @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);
}
/// 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
*
@@ -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.
* @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);
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);
}
/// 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.
* @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);
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);
}
/// 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.
*
@@ -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
*/
@@ -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.
*/
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);
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.
*
* @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);
}
/// 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
*
@@ -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.
* @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);
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.
* @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);
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);
}
/// 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.
*
@@ -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
*/
@@ -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.
*/
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);
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.
*
* @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);
}
/// 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
*
@@ -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.
* @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);
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.
* @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);
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);
}
/// 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.
*
+16 -5
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
*/
@@ -19,8 +19,15 @@
#include "sys/lock.h"
#include "esp_private/rtc_ctrl.h"
#include "esp_private/critical_section.h"
#include "esp_private/periph_ctrl.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
// Enable built-in checks in queue.h in debug builds
@@ -188,8 +195,10 @@ IRAM_ATTR void rtc_isr_noniram_disable(uint32_t cpu)
{
#if SOC_LP_PERIPH_SHARE_INTERRUPT // TODO: IDF-8008
if (rtc_isr_cpu == cpu) {
rtc_intr_enabled |= RTCCNTL.int_ena.val;
RTCCNTL.int_ena.val &= rtc_intr_cache;
RTC_CNTL_ATOMIC() {
rtc_intr_enabled |= RTCCNTL.int_ena.val;
RTCCNTL.int_ena.val &= rtc_intr_cache;
}
}
#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 (rtc_isr_cpu == cpu) {
RTCCNTL.int_ena.val = rtc_intr_enabled;
rtc_intr_enabled = 0;
RTC_CNTL_ATOMIC() {
RTCCNTL.int_ena.val = rtc_intr_enabled;
rtc_intr_enabled = 0;
}
}
#endif
}
+16 -5
View File
@@ -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
*/
@@ -103,6 +103,11 @@ static uint32_t* s_phy_digital_regs_mem = NULL;
static uint8_t s_phy_modem_init_ref = 0;
#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_EMBED
@@ -425,7 +430,9 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void)
#if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock);
if (s_wifi_bt_pd_controller.count++ == 0) {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
}
esp_rom_delay_us(10);
wifi_bt_common_module_enable();
#if CONFIG_IDF_TARGET_ESP32
@@ -436,7 +443,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);
CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU);
#endif
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO);
RTC_CNTL_ATOMIC() {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO);
}
wifi_bt_common_module_disable();
}
_lock_release(&s_wifi_bt_pd_controller.lock);
@@ -450,8 +459,10 @@ void esp_wifi_bt_power_domain_off(void)
#if SOC_PM_MODEM_PD_BY_SW // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock);
if (--s_wifi_bt_pd_controller.count == 0) {
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);
RTC_CNTL_ATOMIC() {
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);
}
}
_lock_release(&s_wifi_bt_pd_controller.lock);
#endif // SOC_PM_MODEM_PD_BY_SW
@@ -499,6 +499,10 @@ config SOC_RTCIO_WAKE_SUPPORTED
bool
default y
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_SPI_PERIPH_NUM
int
default 3
@@ -251,6 +251,10 @@
#define SOC_RTCIO_HOLD_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 ----------------------------------------*/
#define SOC_SPI_PERIPH_NUM 3
#define SOC_SPI_PERIPH_CS_NUM(i) 3
@@ -411,6 +411,10 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int
default 108
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_RTCIO_PIN_COUNT
int
default 0
@@ -186,6 +186,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))
/* 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 --------------------------------------*/
/* No dedicated RTCIO subsystem on ESP32-C2. RTC functions are still supported
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */
@@ -563,6 +563,10 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int
default 108
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
bool
default y
@@ -245,6 +245,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))
/* 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_TGWDT_STOP_WORKAROUND 1
@@ -415,6 +415,10 @@ config SOC_GPIO_CLOCKOUT_CHANNEL_NUM
int
default 3
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_DEDIC_GPIO_HAS_INTERRUPT
bool
default y
@@ -188,6 +188,10 @@
#define SOC_GPIO_CLOCKOUT_BY_IO_MUX (1)
#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 ---------------------------------------*/
#define SOC_DEDIC_GPIO_HAS_INTERRUPT (1) /*!< Dedicated GPIO has its own interrupt source */
@@ -639,6 +639,10 @@ config SOC_RTC_CNTL_TAGMEM_PD_DMA_BUS_WIDTH
int
default 128
config SOC_RTC_CNTL_NEEDS_ATOMIC_ACCESS
bool
default y
config SOC_RTCIO_PIN_COUNT
int
default 22
@@ -265,6 +265,10 @@
#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)
/* 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 --------------------------------------*/
#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,
+16 -3
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
*/
@@ -30,6 +30,13 @@
#include "esp_check.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 {
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_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL");
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
/* 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);
}
#if CONFIG_IDF_TARGET_ESP32
return rtc_isr_register(fn, arg, RTC_CNTL_SAR_INT_ST_M, 0);
#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_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, "ULP ISR is NULL");
REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
/* 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);
}
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
*/
@@ -22,6 +22,13 @@
#include "esp_rom_sys.h"
#include "esp_check.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";
@@ -44,8 +51,10 @@ esp_err_t ulp_riscv_isr_register(intr_handler_t fn, void *arg, uint32_t mask)
/* Register the RTC ISR */
ESP_RETURN_ON_ERROR(rtc_isr_register(fn, arg, mask, 0), TAG, "rtc_isr_register() failed");
/* Enable the interrupt bits */
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask);
/* 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);
}
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 */
mask &= (RTC_CNTL_COCPU_INT_ST_M | RTC_CNTL_COCPU_TRAP_INT_ST_M);
/* Disable the interrupt bits */
CLEAR_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, mask);
/* 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);
}
/* Deregister the RTC ISR */
ESP_RETURN_ON_ERROR(rtc_isr_deregister(fn, arg), TAG, "rtc_isr_deregister() failed");