refactor(hw_support): Use esp_os_enter_critical instead of portENTER_CRITICAL_SAFE in esp_hw_support

This commit is contained in:
C.S.M
2025-06-17 15:40:30 +08:00
parent 22ae972229
commit 4860379677
41 changed files with 522 additions and 482 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -29,6 +29,7 @@
#include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
//For calibration //For calibration
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
@@ -79,11 +80,11 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten)
else { else {
ESP_EARLY_LOGD(TAG, "Calibration eFuse is not configured, use self-calibration for ICode"); ESP_EARLY_LOGD(TAG, "Calibration eFuse is not configured, use self-calibration for ICode");
sar_periph_ctrl_adc_oneshot_power_acquire(); sar_periph_ctrl_adc_oneshot_power_acquire();
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT); adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT);
const bool internal_gnd = true; const bool internal_gnd = true;
init_code = adc_hal_self_calibration(adc_n, atten, internal_gnd); init_code = adc_hal_self_calibration(adc_n, atten, internal_gnd);
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
sar_periph_ctrl_adc_oneshot_power_release(); sar_periph_ctrl_adc_oneshot_power_release();
} }
#else #else
@@ -193,7 +194,7 @@ esp_err_t adc2_wifi_release(void)
return ESP_OK; return ESP_OK;
} }
static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_spinlock = portMUX_INITIALIZER_UNLOCKED;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* For those who use APB_SARADC periph * For those who use APB_SARADC periph
@@ -202,7 +203,7 @@ static int s_adc_digi_ctrlr_cnt;
void adc_apb_periph_claim(void) void adc_apb_periph_claim(void)
{ {
portENTER_CRITICAL(&s_spinlock); esp_os_enter_critical(&s_spinlock);
s_adc_digi_ctrlr_cnt++; s_adc_digi_ctrlr_cnt++;
if (s_adc_digi_ctrlr_cnt == 1) { if (s_adc_digi_ctrlr_cnt == 1) {
ADC_BUS_CLK_ATOMIC() { ADC_BUS_CLK_ATOMIC() {
@@ -214,12 +215,12 @@ void adc_apb_periph_claim(void)
} }
} }
portEXIT_CRITICAL(&s_spinlock); esp_os_exit_critical(&s_spinlock);
} }
void adc_apb_periph_free(void) void adc_apb_periph_free(void)
{ {
portENTER_CRITICAL(&s_spinlock); esp_os_enter_critical(&s_spinlock);
s_adc_digi_ctrlr_cnt--; s_adc_digi_ctrlr_cnt--;
if (s_adc_digi_ctrlr_cnt == 0) { if (s_adc_digi_ctrlr_cnt == 0) {
ADC_BUS_CLK_ATOMIC() { ADC_BUS_CLK_ATOMIC() {
@@ -229,10 +230,10 @@ void adc_apb_periph_free(void)
#endif #endif
} }
} else if (s_adc_digi_ctrlr_cnt < 0) { } else if (s_adc_digi_ctrlr_cnt < 0) {
portEXIT_CRITICAL(&s_spinlock); esp_os_exit_critical(&s_spinlock);
ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__);
abort(); abort();
} }
portEXIT_CRITICAL(&s_spinlock); esp_os_exit_critical(&s_spinlock);
} }

View File

@@ -9,6 +9,7 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "esp_ldo_regulator.h" #include "esp_ldo_regulator.h"
#include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_clk_tree_common.h"
#include "esp_private/critical_section.h"
#include "esp_check.h" #include "esp_check.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
@@ -20,7 +21,7 @@
static const char *TAG = "clk_ctrl_os"; static const char *TAG = "clk_ctrl_os";
#endif #endif
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
static uint8_t s_periph_ref_counts = 0; static uint8_t s_periph_ref_counts = 0;
static uint32_t s_rc_fast_freq_hz = 0; // Frequency of the RC_FAST clock in Hz static uint32_t s_rc_fast_freq_hz = 0; // Frequency of the RC_FAST clock in Hz
@@ -37,20 +38,20 @@ static esp_ldo_channel_handle_t s_ldo_chan = NULL;
bool periph_rtc_dig_clk8m_enable(void) bool periph_rtc_dig_clk8m_enable(void)
{ {
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
if (s_periph_ref_counts == 0) { if (s_periph_ref_counts == 0) {
rtc_dig_clk8m_enable(); rtc_dig_clk8m_enable();
#if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION #if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
s_rc_fast_freq_hz = esp_clk_tree_rc_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT); s_rc_fast_freq_hz = esp_clk_tree_rc_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT);
if (s_rc_fast_freq_hz == 0) { if (s_rc_fast_freq_hz == 0) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
return false; return false;
} }
#endif //SOC_CLK_RC_FAST_SUPPORT_CALIBRATION #endif //SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
} }
s_periph_ref_counts++; s_periph_ref_counts++;
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
return true; return true;
} }
@@ -66,31 +67,31 @@ uint32_t periph_rtc_dig_clk8m_get_freq(void)
void periph_rtc_dig_clk8m_disable(void) void periph_rtc_dig_clk8m_disable(void)
{ {
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
assert(s_periph_ref_counts > 0); assert(s_periph_ref_counts > 0);
s_periph_ref_counts--; s_periph_ref_counts--;
if (s_periph_ref_counts == 0) { if (s_periph_ref_counts == 0) {
s_rc_fast_freq_hz = 0; s_rc_fast_freq_hz = 0;
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
} }
#if SOC_CLK_APLL_SUPPORTED #if SOC_CLK_APLL_SUPPORTED
void periph_rtc_apll_acquire(void) void periph_rtc_apll_acquire(void)
{ {
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
s_apll_ref_cnt++; s_apll_ref_cnt++;
if (s_apll_ref_cnt == 1) { if (s_apll_ref_cnt == 1) {
// For the first time enable APLL, need to set power up // For the first time enable APLL, need to set power up
rtc_clk_apll_enable(true); rtc_clk_apll_enable(true);
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
} }
void periph_rtc_apll_release(void) void periph_rtc_apll_release(void)
{ {
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
assert(s_apll_ref_cnt > 0); assert(s_apll_ref_cnt > 0);
s_apll_ref_cnt--; s_apll_ref_cnt--;
if (s_apll_ref_cnt == 0) { if (s_apll_ref_cnt == 0) {
@@ -98,7 +99,7 @@ void periph_rtc_apll_release(void)
s_cur_apll_freq_hz = 0; s_cur_apll_freq_hz = 0;
rtc_clk_apll_enable(false); rtc_clk_apll_enable(false);
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
} }
esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz) esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz)
@@ -113,7 +114,7 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz
ESP_RETURN_ON_FALSE(apll_freq, ESP_ERR_INVALID_ARG, TAG, "APLL coefficients calculate failed"); ESP_RETURN_ON_FALSE(apll_freq, ESP_ERR_INVALID_ARG, TAG, "APLL coefficients calculate failed");
bool need_config = true; bool need_config = true;
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
/* If APLL is not in use or only one peripheral in use, its frequency can be changed as will /* If APLL is not in use or only one peripheral in use, its frequency can be changed as will
* But when more than one peripheral refers APLL, its frequency is not allowed to change once it is set */ * But when more than one peripheral refers APLL, its frequency is not allowed to change once it is set */
if (s_cur_apll_freq_hz == 0 || s_apll_ref_cnt < 2) { if (s_cur_apll_freq_hz == 0 || s_apll_ref_cnt < 2) {
@@ -122,7 +123,7 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz
apll_freq = s_cur_apll_freq_hz; apll_freq = s_cur_apll_freq_hz;
need_config = false; need_config = false;
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
*real_freq_hz = apll_freq; *real_freq_hz = apll_freq;
if (need_config) { if (need_config) {
@@ -150,13 +151,13 @@ esp_err_t IRAM_ATTR periph_rtc_mpll_acquire(void)
ESP_RETURN_ON_ERROR(esp_ldo_acquire_channel(&ldo_mpll_config, &s_ldo_chan), TAG, "acquire internal LDO for MPLL failed"); ESP_RETURN_ON_ERROR(esp_ldo_acquire_channel(&ldo_mpll_config, &s_ldo_chan), TAG, "acquire internal LDO for MPLL failed");
#endif #endif
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
s_mpll_ref_cnt++; s_mpll_ref_cnt++;
if (s_mpll_ref_cnt == 1) { if (s_mpll_ref_cnt == 1) {
// For the first time enable MPLL, need to set power up // For the first time enable MPLL, need to set power up
rtc_clk_mpll_enable(); rtc_clk_mpll_enable();
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -167,7 +168,7 @@ void periph_rtc_mpll_release(void)
esp_ldo_release_channel(s_ldo_chan); esp_ldo_release_channel(s_ldo_chan);
} }
#endif #endif
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
assert(s_mpll_ref_cnt > 0); assert(s_mpll_ref_cnt > 0);
s_mpll_ref_cnt--; s_mpll_ref_cnt--;
if (s_mpll_ref_cnt == 0) { if (s_mpll_ref_cnt == 0) {
@@ -175,7 +176,7 @@ void periph_rtc_mpll_release(void)
s_cur_mpll_freq_hz = 0; s_cur_mpll_freq_hz = 0;
rtc_clk_mpll_disable(); rtc_clk_mpll_disable();
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
} }
esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz) esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *real_freq_hz)
@@ -185,7 +186,7 @@ esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *re
// Guarantee 'periph_rtc_apll_acquire' has been called before set apll freq // Guarantee 'periph_rtc_apll_acquire' has been called before set apll freq
assert(s_mpll_ref_cnt > 0); assert(s_mpll_ref_cnt > 0);
portENTER_CRITICAL(&periph_spinlock); esp_os_enter_critical(&periph_spinlock);
if (s_cur_mpll_freq_hz == expt_freq_hz) { if (s_cur_mpll_freq_hz == expt_freq_hz) {
goto end; goto end;
} }
@@ -202,7 +203,7 @@ end:
if (real_freq_hz != NULL) { if (real_freq_hz != NULL) {
*real_freq_hz = s_cur_mpll_freq_hz; *real_freq_hz = s_cur_mpll_freq_hz;
} }
portEXIT_CRITICAL(&periph_spinlock); esp_os_exit_critical(&periph_spinlock);
return ret; return ret;
} }
#endif // SOC_CLK_MPLL_SUPPORTED #endif // SOC_CLK_MPLL_SUPPORTED

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -21,6 +21,7 @@
#include "esp_async_memcpy_priv.h" #include "esp_async_memcpy_priv.h"
#include "esp_private/gdma_link.h" #include "esp_private/gdma_link.h"
#include "esp_private/esp_dma_utils.h" #include "esp_private/esp_dma_utils.h"
#include "esp_private/critical_section.h"
#include "hal/cp_dma_hal.h" #include "hal/cp_dma_hal.h"
#include "hal/cp_dma_ll.h" #include "hal/cp_dma_ll.h"
@@ -147,12 +148,12 @@ static esp_err_t mcp_cpdma_del(async_memcpy_context_t *ctx)
static async_memcpy_transaction_t *try_pop_trans_from_ready_queue(async_memcpy_cpdma_context_t *mcp_dma) static async_memcpy_transaction_t *try_pop_trans_from_ready_queue(async_memcpy_cpdma_context_t *mcp_dma)
{ {
async_memcpy_transaction_t *trans = NULL; async_memcpy_transaction_t *trans = NULL;
portENTER_CRITICAL_SAFE(&mcp_dma->spin_lock); esp_os_enter_critical_safe(&mcp_dma->spin_lock);
trans = STAILQ_FIRST(&mcp_dma->ready_queue_head); trans = STAILQ_FIRST(&mcp_dma->ready_queue_head);
if (trans) { if (trans) {
STAILQ_REMOVE_HEAD(&mcp_dma->ready_queue_head, ready_queue_entry); STAILQ_REMOVE_HEAD(&mcp_dma->ready_queue_head, ready_queue_entry);
} }
portEXIT_CRITICAL_SAFE(&mcp_dma->spin_lock); esp_os_exit_critical_safe(&mcp_dma->spin_lock);
return trans; return trans;
} }
@@ -182,12 +183,12 @@ static void try_start_pending_transaction(async_memcpy_cpdma_context_t *mcp_dma)
static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_cpdma_context_t *mcp_dma) static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_cpdma_context_t *mcp_dma)
{ {
async_memcpy_transaction_t *trans = NULL; async_memcpy_transaction_t *trans = NULL;
portENTER_CRITICAL_SAFE(&mcp_dma->spin_lock); esp_os_enter_critical_safe(&mcp_dma->spin_lock);
trans = STAILQ_FIRST(&mcp_dma->idle_queue_head); trans = STAILQ_FIRST(&mcp_dma->idle_queue_head);
if (trans) { if (trans) {
STAILQ_REMOVE_HEAD(&mcp_dma->idle_queue_head, idle_queue_entry); STAILQ_REMOVE_HEAD(&mcp_dma->idle_queue_head, idle_queue_entry);
} }
portEXIT_CRITICAL_SAFE(&mcp_dma->spin_lock); esp_os_exit_critical_safe(&mcp_dma->spin_lock);
return trans; return trans;
} }
@@ -266,10 +267,10 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
trans->cb = cb_isr; trans->cb = cb_isr;
trans->cb_args = cb_args; trans->cb_args = cb_args;
portENTER_CRITICAL(&mcp_dma->spin_lock); esp_os_enter_critical(&mcp_dma->spin_lock);
// insert the trans to ready queue // insert the trans to ready queue
STAILQ_INSERT_TAIL(&mcp_dma->ready_queue_head, trans, ready_queue_entry); STAILQ_INSERT_TAIL(&mcp_dma->ready_queue_head, trans, ready_queue_entry);
portEXIT_CRITICAL(&mcp_dma->spin_lock); esp_os_exit_critical(&mcp_dma->spin_lock);
// check driver state, if there's no running transaction, start a new one // check driver state, if there's no running transaction, start a new one
try_start_pending_transaction(mcp_dma); try_start_pending_transaction(mcp_dma);
@@ -279,9 +280,9 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
err: err:
if (trans) { if (trans) {
// return back the trans to idle queue // return back the trans to idle queue
portENTER_CRITICAL(&mcp_dma->spin_lock); esp_os_enter_critical(&mcp_dma->spin_lock);
STAILQ_INSERT_TAIL(&mcp_dma->idle_queue_head, trans, idle_queue_entry); STAILQ_INSERT_TAIL(&mcp_dma->idle_queue_head, trans, idle_queue_entry);
portEXIT_CRITICAL(&mcp_dma->spin_lock); esp_os_exit_critical(&mcp_dma->spin_lock);
} }
return ret; return ret;
} }
@@ -311,10 +312,10 @@ static void mcp_default_isr_handler(void *args)
} }
trans->cb = NULL; trans->cb = NULL;
portENTER_CRITICAL_ISR(&mcp_dma->spin_lock); esp_os_enter_critical_isr(&mcp_dma->spin_lock);
// insert the trans object to the idle queue // insert the trans object to the idle queue
STAILQ_INSERT_TAIL(&mcp_dma->idle_queue_head, trans, idle_queue_entry); STAILQ_INSERT_TAIL(&mcp_dma->idle_queue_head, trans, idle_queue_entry);
portEXIT_CRITICAL_ISR(&mcp_dma->spin_lock); esp_os_exit_critical_isr(&mcp_dma->spin_lock);
atomic_store(&mcp_dma->fsm, MCP_FSM_IDLE); atomic_store(&mcp_dma->fsm, MCP_FSM_IDLE);
} }

View File

@@ -18,6 +18,7 @@
#include "esp_private/gdma.h" #include "esp_private/gdma.h"
#include "esp_private/gdma_link.h" #include "esp_private/gdma_link.h"
#include "esp_private/esp_dma_utils.h" #include "esp_private/esp_dma_utils.h"
#include "esp_private/critical_section.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_cache.h" #include "esp_cache.h"
#include "esp_async_memcpy.h" #include "esp_async_memcpy.h"
@@ -237,12 +238,12 @@ static esp_err_t mcp_gdma_del(async_memcpy_context_t *ctx)
static async_memcpy_transaction_t *try_pop_trans_from_ready_queue(async_memcpy_gdma_context_t *mcp_gdma) static async_memcpy_transaction_t *try_pop_trans_from_ready_queue(async_memcpy_gdma_context_t *mcp_gdma)
{ {
async_memcpy_transaction_t *trans = NULL; async_memcpy_transaction_t *trans = NULL;
portENTER_CRITICAL_SAFE(&mcp_gdma->spin_lock); esp_os_enter_critical_safe(&mcp_gdma->spin_lock);
trans = STAILQ_FIRST(&mcp_gdma->ready_queue_head); trans = STAILQ_FIRST(&mcp_gdma->ready_queue_head);
if (trans) { if (trans) {
STAILQ_REMOVE_HEAD(&mcp_gdma->ready_queue_head, ready_queue_entry); STAILQ_REMOVE_HEAD(&mcp_gdma->ready_queue_head, ready_queue_entry);
} }
portEXIT_CRITICAL_SAFE(&mcp_gdma->spin_lock); esp_os_exit_critical_safe(&mcp_gdma->spin_lock);
return trans; return trans;
} }
@@ -270,12 +271,12 @@ static void try_start_pending_transaction(async_memcpy_gdma_context_t *mcp_gdma)
static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_gdma_context_t *mcp_gdma) static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_gdma_context_t *mcp_gdma)
{ {
async_memcpy_transaction_t *trans = NULL; async_memcpy_transaction_t *trans = NULL;
portENTER_CRITICAL_SAFE(&mcp_gdma->spin_lock); esp_os_enter_critical_safe(&mcp_gdma->spin_lock);
trans = STAILQ_FIRST(&mcp_gdma->idle_queue_head); trans = STAILQ_FIRST(&mcp_gdma->idle_queue_head);
if (trans) { if (trans) {
STAILQ_REMOVE_HEAD(&mcp_gdma->idle_queue_head, idle_queue_entry); STAILQ_REMOVE_HEAD(&mcp_gdma->idle_queue_head, idle_queue_entry);
} }
portEXIT_CRITICAL_SAFE(&mcp_gdma->spin_lock); esp_os_exit_critical_safe(&mcp_gdma->spin_lock);
return trans; return trans;
} }
@@ -413,10 +414,10 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
trans->cb = cb_isr; trans->cb = cb_isr;
trans->cb_args = cb_args; trans->cb_args = cb_args;
portENTER_CRITICAL(&mcp_gdma->spin_lock); esp_os_enter_critical(&mcp_gdma->spin_lock);
// insert the trans to ready queue // insert the trans to ready queue
STAILQ_INSERT_TAIL(&mcp_gdma->ready_queue_head, trans, ready_queue_entry); STAILQ_INSERT_TAIL(&mcp_gdma->ready_queue_head, trans, ready_queue_entry);
portEXIT_CRITICAL(&mcp_gdma->spin_lock); esp_os_exit_critical(&mcp_gdma->spin_lock);
// check driver state, if there's no running transaction, start a new one // check driver state, if there's no running transaction, start a new one
try_start_pending_transaction(mcp_gdma); try_start_pending_transaction(mcp_gdma);
@@ -426,9 +427,9 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
err: err:
if (trans) { if (trans) {
// return back the trans to idle queue // return back the trans to idle queue
portENTER_CRITICAL(&mcp_gdma->spin_lock); esp_os_enter_critical(&mcp_gdma->spin_lock);
STAILQ_INSERT_TAIL(&mcp_gdma->idle_queue_head, trans, idle_queue_entry); STAILQ_INSERT_TAIL(&mcp_gdma->idle_queue_head, trans, idle_queue_entry);
portEXIT_CRITICAL(&mcp_gdma->spin_lock); esp_os_exit_critical(&mcp_gdma->spin_lock);
} }
return ret; return ret;
} }
@@ -456,10 +457,10 @@ static bool mcp_gdma_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_
} }
trans->cb = NULL; trans->cb = NULL;
portENTER_CRITICAL_ISR(&mcp_gdma->spin_lock); esp_os_enter_critical_isr(&mcp_gdma->spin_lock);
// insert the trans object to the idle queue // insert the trans object to the idle queue
STAILQ_INSERT_TAIL(&mcp_gdma->idle_queue_head, trans, idle_queue_entry); STAILQ_INSERT_TAIL(&mcp_gdma->idle_queue_head, trans, idle_queue_entry);
portEXIT_CRITICAL_ISR(&mcp_gdma->spin_lock); esp_os_exit_critical_isr(&mcp_gdma->spin_lock);
atomic_store(&mcp_gdma->fsm, MCP_FSM_IDLE); atomic_store(&mcp_gdma->fsm, MCP_FSM_IDLE);
} }

View File

@@ -17,6 +17,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "dma2d_priv.h" #include "dma2d_priv.h"
#include "esp_private/dma2d.h" #include "esp_private/dma2d.h"
#include "hal/dma2d_hal.h" #include "hal/dma2d_hal.h"
@@ -142,9 +143,9 @@ static bool acquire_free_channels_for_trans(dma2d_group_t *dma2d_group, const dm
// Record its bundled TX channels, to be freed in the isr // Record its bundled TX channels, to be freed in the isr
dma2d_rx_channel_t *rx_chan = dma2d_group->rx_chans[channel_id]; dma2d_rx_channel_t *rx_chan = dma2d_group->rx_chans[channel_id];
portENTER_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_enter_critical_safe(&rx_chan->base.spinlock);
rx_chan->bundled_tx_channel_mask = bundled_tx_channel_mask; rx_chan->bundled_tx_channel_mask = bundled_tx_channel_mask;
portEXIT_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_exit_critical_safe(&rx_chan->base.spinlock);
} else { } else {
found = false; found = false;
goto revert; goto revert;
@@ -175,7 +176,7 @@ static bool free_up_channels(dma2d_group_t *group, dma2d_rx_channel_t *rx_chan)
uint32_t tx_periph_sel_id_mask = 0; uint32_t tx_periph_sel_id_mask = 0;
uint32_t rx_periph_sel_id_mask = 0; uint32_t rx_periph_sel_id_mask = 0;
// Disable RX channel interrupt // Disable RX channel interrupt
portENTER_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_enter_critical_safe(&rx_chan->base.spinlock);
dma2d_ll_rx_enable_interrupt(group->hal.dev, channel_id, UINT32_MAX, false); dma2d_ll_rx_enable_interrupt(group->hal.dev, channel_id, UINT32_MAX, false);
// Reset RX channel event related pointers and flags // Reset RX channel event related pointers and flags
rx_chan->on_recv_eof = NULL; rx_chan->on_recv_eof = NULL;
@@ -187,14 +188,14 @@ static bool free_up_channels(dma2d_group_t *group, dma2d_rx_channel_t *rx_chan)
// Record its periph_sel_id // Record its periph_sel_id
assert(rx_chan->base.status.periph_sel_id != -1); assert(rx_chan->base.status.periph_sel_id != -1);
rx_periph_sel_id_mask |= (1 << rx_chan->base.status.periph_sel_id); rx_periph_sel_id_mask |= (1 << rx_chan->base.status.periph_sel_id);
portEXIT_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_exit_critical_safe(&rx_chan->base.spinlock);
// For every bundled TX channels: // For every bundled TX channels:
while (rx_chan->bundled_tx_channel_mask) { while (rx_chan->bundled_tx_channel_mask) {
uint32_t nbit = __builtin_ffs(rx_chan->bundled_tx_channel_mask) - 1; uint32_t nbit = __builtin_ffs(rx_chan->bundled_tx_channel_mask) - 1;
rx_chan->bundled_tx_channel_mask &= ~(1 << nbit); rx_chan->bundled_tx_channel_mask &= ~(1 << nbit);
dma2d_tx_channel_t *tx_chan = group->tx_chans[nbit]; dma2d_tx_channel_t *tx_chan = group->tx_chans[nbit];
// Disable TX channel interrupt // Disable TX channel interrupt
portENTER_CRITICAL_SAFE(&tx_chan->base.spinlock); esp_os_enter_critical_safe(&tx_chan->base.spinlock);
dma2d_ll_tx_enable_interrupt(group->hal.dev, nbit, UINT32_MAX, false); dma2d_ll_tx_enable_interrupt(group->hal.dev, nbit, UINT32_MAX, false);
// Reset TX channel event related pointers // Reset TX channel event related pointers
tx_chan->on_desc_done = NULL; tx_chan->on_desc_done = NULL;
@@ -205,7 +206,7 @@ static bool free_up_channels(dma2d_group_t *group, dma2d_rx_channel_t *rx_chan)
// Record its periph_sel_id // Record its periph_sel_id
assert(tx_chan->base.status.periph_sel_id != -1); assert(tx_chan->base.status.periph_sel_id != -1);
tx_periph_sel_id_mask |= (1 << tx_chan->base.status.periph_sel_id); tx_periph_sel_id_mask |= (1 << tx_chan->base.status.periph_sel_id);
portEXIT_CRITICAL_SAFE(&tx_chan->base.spinlock); esp_os_exit_critical_safe(&tx_chan->base.spinlock);
} }
// Channel functionality flags will be reset and assigned new values inside `acquire_free_channels_for_trans` // Channel functionality flags will be reset and assigned new values inside `acquire_free_channels_for_trans`
// Channel reset will always be done at `dma2d_connect` (i.e. when the channel is selected for a new transaction) // Channel reset will always be done at `dma2d_connect` (i.e. when the channel is selected for a new transaction)
@@ -215,7 +216,7 @@ static bool free_up_channels(dma2d_group_t *group, dma2d_rx_channel_t *rx_chan)
const dma2d_trans_config_t *next_trans = NULL; const dma2d_trans_config_t *next_trans = NULL;
dma2d_trans_channel_info_t channel_handle_array[DMA2D_MAX_CHANNEL_NUM_PER_TRANSACTION]; dma2d_trans_channel_info_t channel_handle_array[DMA2D_MAX_CHANNEL_NUM_PER_TRANSACTION];
portENTER_CRITICAL_SAFE(&group->spinlock); esp_os_enter_critical_safe(&group->spinlock);
// Release channels // Release channels
group->tx_channel_free_mask |= bundled_tx_channel_mask; group->tx_channel_free_mask |= bundled_tx_channel_mask;
group->rx_channel_free_mask |= (1 << channel_id); group->rx_channel_free_mask |= (1 << channel_id);
@@ -233,7 +234,7 @@ static bool free_up_channels(dma2d_group_t *group, dma2d_rx_channel_t *rx_chan)
if (channels_found) { if (channels_found) {
TAILQ_REMOVE(&group->pending_trans_tailq, next_trans_elm, entry); TAILQ_REMOVE(&group->pending_trans_tailq, next_trans_elm, entry);
} }
portEXIT_CRITICAL_SAFE(&group->spinlock); esp_os_exit_critical_safe(&group->spinlock);
if (channels_found) { if (channels_found) {
// If the transaction can be processed, let consumer handle the transaction // If the transaction can be processed, let consumer handle the transaction
@@ -549,7 +550,7 @@ esp_err_t dma2d_connect(dma2d_channel_handle_t dma2d_chan, const dma2d_trigger_t
periph_m2m_free_id_mask = &group->rx_periph_m2m_free_id_mask; periph_m2m_free_id_mask = &group->rx_periph_m2m_free_id_mask;
periph_m2m_available_id_mask = DMA2D_LL_RX_CHANNEL_PERIPH_M2M_AVAILABLE_ID_MASK; periph_m2m_available_id_mask = DMA2D_LL_RX_CHANNEL_PERIPH_M2M_AVAILABLE_ID_MASK;
} }
portENTER_CRITICAL_SAFE(&group->spinlock); esp_os_enter_critical_safe(&group->spinlock);
if (trig_periph->periph == DMA2D_TRIG_PERIPH_M2M) { if (trig_periph->periph == DMA2D_TRIG_PERIPH_M2M) {
if (peri_sel_id == -1) { if (peri_sel_id == -1) {
// Unspecified periph_sel_id, decide by the driver // Unspecified periph_sel_id, decide by the driver
@@ -565,10 +566,10 @@ esp_err_t dma2d_connect(dma2d_channel_handle_t dma2d_chan, const dma2d_trigger_t
dma2d_chan->status.periph_sel_id = peri_sel_id; dma2d_chan->status.periph_sel_id = peri_sel_id;
*periph_m2m_free_id_mask &= ~(1 << peri_sel_id); // acquire m2m periph_sel_id *periph_m2m_free_id_mask &= ~(1 << peri_sel_id); // acquire m2m periph_sel_id
} }
portEXIT_CRITICAL_SAFE(&group->spinlock); esp_os_exit_critical_safe(&group->spinlock);
ESP_GOTO_ON_FALSE_ISR(peri_sel_id >= 0, ESP_ERR_INVALID_ARG, err, TAG, "invalid periph_sel_id"); ESP_GOTO_ON_FALSE_ISR(peri_sel_id >= 0, ESP_ERR_INVALID_ARG, err, TAG, "invalid periph_sel_id");
portENTER_CRITICAL_SAFE(&dma2d_chan->spinlock); esp_os_enter_critical_safe(&dma2d_chan->spinlock);
if (dma2d_chan->direction == DMA2D_CHANNEL_DIRECTION_TX) { if (dma2d_chan->direction == DMA2D_CHANNEL_DIRECTION_TX) {
dma2d_ll_tx_stop(group->hal.dev, channel_id); dma2d_ll_tx_stop(group->hal.dev, channel_id);
dma2d_hal_tx_reset_channel(&group->hal, channel_id); dma2d_hal_tx_reset_channel(&group->hal, channel_id);
@@ -619,7 +620,7 @@ esp_err_t dma2d_connect(dma2d_channel_handle_t dma2d_chan, const dma2d_trigger_t
dma2d_ll_rx_enable_interrupt(group->hal.dev, channel_id, UINT32_MAX, false); // disable all interrupt events dma2d_ll_rx_enable_interrupt(group->hal.dev, channel_id, UINT32_MAX, false); // disable all interrupt events
dma2d_ll_rx_clear_interrupt_status(group->hal.dev, channel_id, UINT32_MAX); // clear all pending events dma2d_ll_rx_clear_interrupt_status(group->hal.dev, channel_id, UINT32_MAX); // clear all pending events
} }
portEXIT_CRITICAL_SAFE(&dma2d_chan->spinlock); esp_os_exit_critical_safe(&dma2d_chan->spinlock);
err: err:
return ret; return ret;
@@ -647,14 +648,14 @@ esp_err_t dma2d_register_tx_event_callbacks(dma2d_channel_handle_t dma2d_chan, d
// Enable/Disable 2D-DMA interrupt events for the TX channel // Enable/Disable 2D-DMA interrupt events for the TX channel
uint32_t mask = 0; uint32_t mask = 0;
portENTER_CRITICAL_SAFE(&tx_chan->base.spinlock); esp_os_enter_critical_safe(&tx_chan->base.spinlock);
if (cbs->on_desc_done) { if (cbs->on_desc_done) {
tx_chan->on_desc_done = cbs->on_desc_done; tx_chan->on_desc_done = cbs->on_desc_done;
mask |= DMA2D_LL_EVENT_TX_DONE; mask |= DMA2D_LL_EVENT_TX_DONE;
} }
tx_chan->user_data = user_data; tx_chan->user_data = user_data;
dma2d_ll_tx_enable_interrupt(group->hal.dev, tx_chan->base.channel_id, mask, true); dma2d_ll_tx_enable_interrupt(group->hal.dev, tx_chan->base.channel_id, mask, true);
portEXIT_CRITICAL_SAFE(&tx_chan->base.spinlock); esp_os_exit_critical_safe(&tx_chan->base.spinlock);
err: err:
return ret; return ret;
@@ -685,7 +686,7 @@ esp_err_t dma2d_register_rx_event_callbacks(dma2d_channel_handle_t dma2d_chan, d
// Enable/Disable 2D-DMA interrupt events for the RX channel // Enable/Disable 2D-DMA interrupt events for the RX channel
uint32_t mask = 0; uint32_t mask = 0;
portENTER_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_enter_critical_safe(&rx_chan->base.spinlock);
if (cbs->on_recv_eof) { if (cbs->on_recv_eof) {
rx_chan->on_recv_eof = cbs->on_recv_eof; rx_chan->on_recv_eof = cbs->on_recv_eof;
mask |= DMA2D_LL_EVENT_RX_SUC_EOF; mask |= DMA2D_LL_EVENT_RX_SUC_EOF;
@@ -701,7 +702,7 @@ esp_err_t dma2d_register_rx_event_callbacks(dma2d_channel_handle_t dma2d_chan, d
rx_chan->user_data = user_data; rx_chan->user_data = user_data;
dma2d_ll_rx_enable_interrupt(group->hal.dev, rx_chan->base.channel_id, mask, true); dma2d_ll_rx_enable_interrupt(group->hal.dev, rx_chan->base.channel_id, mask, true);
portEXIT_CRITICAL_SAFE(&rx_chan->base.spinlock); esp_os_exit_critical_safe(&rx_chan->base.spinlock);
err: err:
return ret; return ret;
@@ -792,13 +793,13 @@ esp_err_t dma2d_reset(dma2d_channel_handle_t dma2d_chan)
dma2d_group_t *group = dma2d_chan->group; dma2d_group_t *group = dma2d_chan->group;
int channel_id = dma2d_chan->channel_id; int channel_id = dma2d_chan->channel_id;
portENTER_CRITICAL_SAFE(&dma2d_chan->spinlock); esp_os_enter_critical_safe(&dma2d_chan->spinlock);
if (dma2d_chan->direction == DMA2D_CHANNEL_DIRECTION_TX) { if (dma2d_chan->direction == DMA2D_CHANNEL_DIRECTION_TX) {
dma2d_hal_tx_reset_channel(&group->hal, channel_id); dma2d_hal_tx_reset_channel(&group->hal, channel_id);
} else { } else {
dma2d_hal_rx_reset_channel(&group->hal, channel_id); dma2d_hal_rx_reset_channel(&group->hal, channel_id);
} }
portEXIT_CRITICAL_SAFE(&dma2d_chan->spinlock); esp_os_exit_critical_safe(&dma2d_chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -931,7 +932,7 @@ esp_err_t dma2d_enqueue(dma2d_pool_handle_t dma2d_pool, const dma2d_trans_config
trans_placeholder->desc = trans_desc; trans_placeholder->desc = trans_desc;
dma2d_trans_channel_info_t channel_handle_array[DMA2D_MAX_CHANNEL_NUM_PER_TRANSACTION]; dma2d_trans_channel_info_t channel_handle_array[DMA2D_MAX_CHANNEL_NUM_PER_TRANSACTION];
portENTER_CRITICAL_SAFE(&dma2d_group->spinlock); esp_os_enter_critical_safe(&dma2d_group->spinlock);
bool enqueue = !acquire_free_channels_for_trans(dma2d_group, trans_desc, channel_handle_array); bool enqueue = !acquire_free_channels_for_trans(dma2d_group, trans_desc, channel_handle_array);
if (enqueue) { if (enqueue) {
if (!trans_desc->specified_tx_channel_mask && !trans_desc->specified_rx_channel_mask) { if (!trans_desc->specified_tx_channel_mask && !trans_desc->specified_rx_channel_mask) {
@@ -940,7 +941,7 @@ esp_err_t dma2d_enqueue(dma2d_pool_handle_t dma2d_pool, const dma2d_trans_config
TAILQ_INSERT_HEAD(&dma2d_group->pending_trans_tailq, trans_placeholder, entry); TAILQ_INSERT_HEAD(&dma2d_group->pending_trans_tailq, trans_placeholder, entry);
} }
} }
portEXIT_CRITICAL_SAFE(&dma2d_group->spinlock); esp_os_exit_critical_safe(&dma2d_group->spinlock);
if (!enqueue) { if (!enqueue) {
// Free channels available, start transaction immediately // Free channels available, start transaction immediately
// Store the acquired rx_chan into trans_placeholder (dma2d_trans_t) in case upper driver later need it to call `dma2d_force_end` // Store the acquired rx_chan into trans_placeholder (dma2d_trans_t) in case upper driver later need it to call `dma2d_force_end`
@@ -968,7 +969,7 @@ esp_err_t dma2d_force_end(dma2d_trans_t *trans, bool *need_yield)
bool in_flight = false; bool in_flight = false;
// We judge whether the transaction is in-flight by checking the RX channel it uses is being occupied or free // We judge whether the transaction is in-flight by checking the RX channel it uses is being occupied or free
portENTER_CRITICAL_SAFE(&group->spinlock); esp_os_enter_critical_safe(&group->spinlock);
if (!(group->rx_channel_free_mask & (1 << trans->rx_chan->channel_id))) { if (!(group->rx_channel_free_mask & (1 << trans->rx_chan->channel_id))) {
in_flight = true; in_flight = true;
dma2d_ll_rx_enable_interrupt(group->hal.dev, trans->rx_chan->channel_id, UINT32_MAX, false); dma2d_ll_rx_enable_interrupt(group->hal.dev, trans->rx_chan->channel_id, UINT32_MAX, false);
@@ -976,7 +977,7 @@ esp_err_t dma2d_force_end(dma2d_trans_t *trans, bool *need_yield)
// 1. when TX or RX is transferring data (channel not in idle state) // 1. when TX or RX is transferring data (channel not in idle state)
// 2. TX successfully passed data to the module, but module cannot process the data, so RX has no data to delivery (RX channel in idle state) // 2. TX successfully passed data to the module, but module cannot process the data, so RX has no data to delivery (RX channel in idle state)
} }
portEXIT_CRITICAL_SAFE(&group->spinlock); esp_os_exit_critical_safe(&group->spinlock);
ESP_RETURN_ON_FALSE_ISR(in_flight, ESP_ERR_INVALID_STATE, TAG, "transaction not in-flight"); ESP_RETURN_ON_FALSE_ISR(in_flight, ESP_ERR_INVALID_STATE, TAG, "transaction not in-flight");
dma2d_rx_channel_t *rx_chan = group->rx_chans[trans->rx_chan->channel_id]; dma2d_rx_channel_t *rx_chan = group->rx_chans[trans->rx_chan->channel_id];

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -25,6 +25,7 @@
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/dw_gdma.h" #include "esp_private/dw_gdma.h"
#include "esp_private/critical_section.h"
#include "hal/dw_gdma_hal.h" #include "hal/dw_gdma_hal.h"
#include "hal/dw_gdma_ll.h" #include "hal/dw_gdma_ll.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
@@ -176,7 +177,7 @@ static esp_err_t channel_register_to_group(dw_gdma_channel_t *chan)
group = dw_gdma_acquire_group_handle(i); group = dw_gdma_acquire_group_handle(i);
ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no mem for group(%d)", i); ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no mem for group(%d)", i);
// loop to search free channel in the group // loop to search free channel in the group
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
for (int j = 0; j < DW_GDMA_LL_CHANNELS_PER_GROUP; j++) { for (int j = 0; j < DW_GDMA_LL_CHANNELS_PER_GROUP; j++) {
if (group->channels[j] == NULL) { if (group->channels[j] == NULL) {
group->channels[j] = chan; group->channels[j] = chan;
@@ -184,7 +185,7 @@ static esp_err_t channel_register_to_group(dw_gdma_channel_t *chan)
break; break;
} }
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
if (chan_id < 0) { if (chan_id < 0) {
dw_gdma_release_group_handle(group); dw_gdma_release_group_handle(group);
} else { } else {
@@ -201,9 +202,9 @@ static void channel_unregister_from_group(dw_gdma_channel_t *chan)
{ {
dw_gdma_group_t *group = chan->group; dw_gdma_group_t *group = chan->group;
int chan_id = chan->chan_id; int chan_id = chan->chan_id;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->channels[chan_id] = NULL; group->channels[chan_id] = NULL;
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
// channel has a reference on group, release it now // channel has a reference on group, release it now
dw_gdma_release_group_handle(group); dw_gdma_release_group_handle(group);
} }
@@ -250,13 +251,13 @@ esp_err_t dw_gdma_new_channel(const dw_gdma_channel_alloc_config_t *config, dw_g
// all channels in the same group should use the same interrupt priority // all channels in the same group should use the same interrupt priority
bool intr_priority_conflict = false; bool intr_priority_conflict = false;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
if (group->intr_priority == -1) { if (group->intr_priority == -1) {
group->intr_priority = config->intr_priority; group->intr_priority = config->intr_priority;
} else if (config->intr_priority != 0) { } else if (config->intr_priority != 0) {
intr_priority_conflict = (group->intr_priority != config->intr_priority); intr_priority_conflict = (group->intr_priority != config->intr_priority);
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
ESP_GOTO_ON_FALSE(!intr_priority_conflict, ESP_ERR_INVALID_STATE, err, TAG, "intr_priority conflict, already is %d but attempt to %d", group->intr_priority, config->intr_priority); ESP_GOTO_ON_FALSE(!intr_priority_conflict, ESP_ERR_INVALID_STATE, err, TAG, "intr_priority conflict, already is %d but attempt to %d", group->intr_priority, config->intr_priority);
// basic initialization // basic initialization
@@ -349,9 +350,9 @@ esp_err_t dw_gdma_channel_lock(dw_gdma_channel_handle_t chan, dw_gdma_lock_level
int chan_id = chan->chan_id; int chan_id = chan->chan_id;
// the lock control bit is located in a cfg register, with other configuration bits // the lock control bit is located in a cfg register, with other configuration bits
portENTER_CRITICAL(&chan->spinlock); esp_os_enter_critical(&chan->spinlock);
dw_gdma_ll_channel_lock(hal->dev, chan_id, level); dw_gdma_ll_channel_lock(hal->dev, chan_id, level);
portEXIT_CRITICAL(&chan->spinlock); esp_os_exit_critical(&chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -362,9 +363,9 @@ esp_err_t dw_gdma_channel_unlock(dw_gdma_channel_handle_t chan)
int chan_id = chan->chan_id; int chan_id = chan->chan_id;
// the lock control bit is located in a cfg register, with other configuration bits // the lock control bit is located in a cfg register, with other configuration bits
portENTER_CRITICAL(&chan->spinlock); esp_os_enter_critical(&chan->spinlock);
dw_gdma_ll_channel_unlock(hal->dev, chan_id); dw_gdma_ll_channel_unlock(hal->dev, chan_id);
portEXIT_CRITICAL(&chan->spinlock); esp_os_exit_critical(&chan->spinlock);
return ESP_OK; return ESP_OK;
} }

View File

@@ -29,6 +29,7 @@
#include "gdma_priv.h" #include "gdma_priv.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_flash_encrypt.h" #include "esp_flash_encrypt.h"
#include "esp_private/critical_section.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
#include "esp_private/gdma_sleep_retention.h" #include "esp_private/gdma_sleep_retention.h"
@@ -101,9 +102,9 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear
ESP_GOTO_ON_FALSE(pair, ESP_ERR_INVALID_ARG, err, TAG, "invalid sibling channel"); ESP_GOTO_ON_FALSE(pair, ESP_ERR_INVALID_ARG, err, TAG, "invalid sibling channel");
ESP_GOTO_ON_FALSE(config->sibling_chan->direction != config->direction, ESP_ERR_INVALID_ARG, err, TAG, "sibling channel should have a different direction"); ESP_GOTO_ON_FALSE(config->sibling_chan->direction != config->direction, ESP_ERR_INVALID_ARG, err, TAG, "sibling channel should have a different direction");
group = pair->group; group = pair->group;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->pair_ref_counts[pair->pair_id]++; // channel obtains a reference to pair group->pair_ref_counts[pair->pair_id]++; // channel obtains a reference to pair
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
goto search_done; // skip the search path below if user has specify a sibling channel goto search_done; // skip the search path below if user has specify a sibling channel
} }
@@ -118,17 +119,17 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear
for (int j = 0; j < pairs_per_group && search_code; j++) { // loop to search pair for (int j = 0; j < pairs_per_group && search_code; j++) { // loop to search pair
pair = gdma_acquire_pair_handle(group, j); pair = gdma_acquire_pair_handle(group, j);
ESP_GOTO_ON_FALSE(pair, ESP_ERR_NO_MEM, err, TAG, "no mem for pair(%d,%d)", i, j); ESP_GOTO_ON_FALSE(pair, ESP_ERR_NO_MEM, err, TAG, "no mem for pair(%d,%d)", i, j);
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
if (!(search_code & pair->occupy_code)) { // pair has suitable position for acquired channel(s) if (!(search_code & pair->occupy_code)) { // pair has suitable position for acquired channel(s)
pair->occupy_code |= search_code; pair->occupy_code |= search_code;
search_code = 0; // exit search loop search_code = 0; // exit search loop
} }
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
// found a pair that satisfies the search condition // found a pair that satisfies the search condition
if (search_code == 0) { if (search_code == 0) {
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->pair_ref_counts[pair->pair_id]++; // channel obtains a reference to pair group->pair_ref_counts[pair->pair_id]++; // channel obtains a reference to pair
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
} }
gdma_release_pair_handle(pair); gdma_release_pair_handle(pair);
} // loop used to search pair } // loop used to search pair
@@ -270,23 +271,23 @@ esp_err_t gdma_connect(gdma_channel_handle_t dma_chan, gdma_trigger_t trig_perip
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX) { if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX) {
if (trig_periph.instance_id >= 0) { if (trig_periph.instance_id >= 0) {
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
if (group->tx_periph_in_use_mask & (1 << trig_periph.instance_id)) { if (group->tx_periph_in_use_mask & (1 << trig_periph.instance_id)) {
periph_conflict = true; periph_conflict = true;
} else { } else {
group->tx_periph_in_use_mask |= (1 << trig_periph.instance_id); group->tx_periph_in_use_mask |= (1 << trig_periph.instance_id);
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
} }
} else { } else {
if (trig_periph.instance_id >= 0) { if (trig_periph.instance_id >= 0) {
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
if (group->rx_periph_in_use_mask & (1 << trig_periph.instance_id)) { if (group->rx_periph_in_use_mask & (1 << trig_periph.instance_id)) {
periph_conflict = true; periph_conflict = true;
} else { } else {
group->rx_periph_in_use_mask |= (1 << trig_periph.instance_id); group->rx_periph_in_use_mask |= (1 << trig_periph.instance_id);
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
} }
} }
@@ -308,15 +309,15 @@ esp_err_t gdma_disconnect(gdma_channel_handle_t dma_chan)
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX) { if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX) {
if (save_periph_id >= 0) { if (save_periph_id >= 0) {
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->tx_periph_in_use_mask &= ~(1 << save_periph_id); group->tx_periph_in_use_mask &= ~(1 << save_periph_id);
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
} }
} else { } else {
if (save_periph_id >= 0) { if (save_periph_id >= 0) {
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->rx_periph_in_use_mask &= ~(1 << save_periph_id); group->rx_periph_in_use_mask &= ~(1 << save_periph_id);
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
} }
} }
@@ -333,10 +334,10 @@ esp_err_t gdma_get_free_m2m_trig_id_mask(gdma_channel_handle_t dma_chan, uint32_
gdma_group_t *group = pair->group; gdma_group_t *group = pair->group;
uint32_t free_mask = group->hal.priv_data->m2m_free_periph_mask; uint32_t free_mask = group->hal.priv_data->m2m_free_periph_mask;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
free_mask &= ~(group->tx_periph_in_use_mask); free_mask &= ~(group->tx_periph_in_use_mask);
free_mask &= ~(group->rx_periph_in_use_mask); free_mask &= ~(group->rx_periph_in_use_mask);
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
*mask = free_mask; *mask = free_mask;
return ESP_OK; return ESP_OK;
@@ -476,10 +477,10 @@ esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_
ESP_RETURN_ON_ERROR(gdma_install_tx_interrupt(tx_chan), TAG, "install interrupt service failed"); ESP_RETURN_ON_ERROR(gdma_install_tx_interrupt(tx_chan), TAG, "install interrupt service failed");
// enable/disable GDMA interrupt events for TX channel // enable/disable GDMA interrupt events for TX channel
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_EOF, cbs->on_trans_eof != NULL); gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_EOF, cbs->on_trans_eof != NULL);
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_DESC_ERROR, cbs->on_descr_err != NULL); gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_DESC_ERROR, cbs->on_descr_err != NULL);
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
memcpy(&tx_chan->cbs, cbs, sizeof(gdma_tx_event_callbacks_t)); memcpy(&tx_chan->cbs, cbs, sizeof(gdma_tx_event_callbacks_t));
tx_chan->user_data = user_data; tx_chan->user_data = user_data;
@@ -520,11 +521,11 @@ esp_err_t gdma_register_rx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_
ESP_RETURN_ON_ERROR(gdma_install_rx_interrupt(rx_chan), TAG, "install interrupt service failed"); ESP_RETURN_ON_ERROR(gdma_install_rx_interrupt(rx_chan), TAG, "install interrupt service failed");
// enable/disable GDMA interrupt events for RX channel // enable/disable GDMA interrupt events for RX channel
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_SUC_EOF | GDMA_LL_EVENT_RX_ERR_EOF, cbs->on_recv_eof != NULL); gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_SUC_EOF | GDMA_LL_EVENT_RX_ERR_EOF, cbs->on_recv_eof != NULL);
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_DESC_ERROR, cbs->on_descr_err != NULL); gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_DESC_ERROR, cbs->on_descr_err != NULL);
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_DONE, cbs->on_recv_done != NULL); gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, GDMA_LL_EVENT_RX_DONE, cbs->on_recv_done != NULL);
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
memcpy(&rx_chan->cbs, cbs, sizeof(gdma_rx_event_callbacks_t)); memcpy(&rx_chan->cbs, cbs, sizeof(gdma_rx_event_callbacks_t));
rx_chan->user_data = user_data; rx_chan->user_data = user_data;
@@ -542,9 +543,9 @@ esp_err_t gdma_start(gdma_channel_handle_t dma_chan, intptr_t desc_base_addr)
gdma_group_t *group = pair->group; gdma_group_t *group = pair->group;
gdma_hal_context_t *hal = &group->hal; gdma_hal_context_t *hal = &group->hal;
portENTER_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_enter_critical_safe(&dma_chan->spinlock);
gdma_hal_start_with_desc(hal, pair->pair_id, dma_chan->direction, desc_base_addr); gdma_hal_start_with_desc(hal, pair->pair_id, dma_chan->direction, desc_base_addr);
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_exit_critical_safe(&dma_chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -557,9 +558,9 @@ esp_err_t gdma_stop(gdma_channel_handle_t dma_chan)
gdma_group_t *group = pair->group; gdma_group_t *group = pair->group;
gdma_hal_context_t *hal = &group->hal; gdma_hal_context_t *hal = &group->hal;
portENTER_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_enter_critical_safe(&dma_chan->spinlock);
gdma_hal_stop(hal, pair->pair_id, dma_chan->direction); gdma_hal_stop(hal, pair->pair_id, dma_chan->direction);
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_exit_critical_safe(&dma_chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -571,9 +572,9 @@ esp_err_t gdma_append(gdma_channel_handle_t dma_chan)
gdma_group_t *group = pair->group; gdma_group_t *group = pair->group;
gdma_hal_context_t *hal = &group->hal; gdma_hal_context_t *hal = &group->hal;
portENTER_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_enter_critical_safe(&dma_chan->spinlock);
gdma_hal_append(hal, pair->pair_id, dma_chan->direction); gdma_hal_append(hal, pair->pair_id, dma_chan->direction);
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_exit_critical_safe(&dma_chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -585,9 +586,9 @@ esp_err_t gdma_reset(gdma_channel_handle_t dma_chan)
gdma_group_t *group = pair->group; gdma_group_t *group = pair->group;
gdma_hal_context_t *hal = &group->hal; gdma_hal_context_t *hal = &group->hal;
portENTER_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_enter_critical_safe(&dma_chan->spinlock);
gdma_hal_reset(hal, pair->pair_id, dma_chan->direction); gdma_hal_reset(hal, pair->pair_id, dma_chan->direction);
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock); esp_os_exit_critical_safe(&dma_chan->spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -597,7 +598,7 @@ static void gdma_release_group_handle(gdma_group_t *group)
int group_id = group->group_id; int group_id = group->group_id;
bool do_deinitialize = false; bool do_deinitialize = false;
portENTER_CRITICAL(&s_platform.spinlock); esp_os_enter_critical(&s_platform.spinlock);
s_platform.group_ref_counts[group_id]--; s_platform.group_ref_counts[group_id]--;
if (s_platform.group_ref_counts[group_id] == 0) { if (s_platform.group_ref_counts[group_id] == 0) {
assert(s_platform.groups[group_id]); assert(s_platform.groups[group_id]);
@@ -605,7 +606,7 @@ static void gdma_release_group_handle(gdma_group_t *group)
// deregister from the platform // deregister from the platform
s_platform.groups[group_id] = NULL; s_platform.groups[group_id] = NULL;
} }
portEXIT_CRITICAL(&s_platform.spinlock); esp_os_exit_critical(&s_platform.spinlock);
if (do_deinitialize) { if (do_deinitialize) {
gdma_hal_deinit(&group->hal); gdma_hal_deinit(&group->hal);
@@ -626,7 +627,7 @@ static gdma_group_t *gdma_acquire_group_handle(int group_id, void (*hal_init)(gd
goto out; goto out;
} }
portENTER_CRITICAL(&s_platform.spinlock); esp_os_enter_critical(&s_platform.spinlock);
if (!s_platform.groups[group_id]) { if (!s_platform.groups[group_id]) {
new_group = true; new_group = true;
group = pre_alloc_group; group = pre_alloc_group;
@@ -636,7 +637,7 @@ static gdma_group_t *gdma_acquire_group_handle(int group_id, void (*hal_init)(gd
} }
// someone acquired the group handle means we have a new object that refer to this group // someone acquired the group handle means we have a new object that refer to this group
s_platform.group_ref_counts[group_id]++; s_platform.group_ref_counts[group_id]++;
portEXIT_CRITICAL(&s_platform.spinlock); esp_os_exit_critical(&s_platform.spinlock);
if (new_group) { if (new_group) {
group->group_id = group_id; group->group_id = group_id;
@@ -667,14 +668,14 @@ static void gdma_release_pair_handle(gdma_pair_t *pair)
int pair_id = pair->pair_id; int pair_id = pair->pair_id;
bool do_deinitialize = false; bool do_deinitialize = false;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->pair_ref_counts[pair_id]--; group->pair_ref_counts[pair_id]--;
if (group->pair_ref_counts[pair_id] == 0) { if (group->pair_ref_counts[pair_id] == 0) {
assert(group->pairs[pair_id]); assert(group->pairs[pair_id]);
do_deinitialize = true; do_deinitialize = true;
group->pairs[pair_id] = NULL; // deregister from pair group->pairs[pair_id] = NULL; // deregister from pair
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
if (do_deinitialize) { if (do_deinitialize) {
free(pair); free(pair);
@@ -695,7 +696,7 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id)
goto out; goto out;
} }
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
if (!group->pairs[pair_id]) { if (!group->pairs[pair_id]) {
new_pair = true; new_pair = true;
pair = pre_alloc_pair; pair = pre_alloc_pair;
@@ -706,17 +707,17 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id)
} }
// someone acquired the pair handle means we have a new object that refer to this pair // someone acquired the pair handle means we have a new object that refer to this pair
group->pair_ref_counts[pair_id]++; group->pair_ref_counts[pair_id]++;
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
if (new_pair) { if (new_pair) {
pair->group = group; pair->group = group;
pair->pair_id = pair_id; pair->pair_id = pair_id;
pair->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; pair->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&s_platform.spinlock); esp_os_enter_critical(&s_platform.spinlock);
// pair obtains a reference to group, so increase it // pair obtains a reference to group, so increase it
s_platform.group_ref_counts[group->group_id]++; s_platform.group_ref_counts[group->group_id]++;
portEXIT_CRITICAL(&s_platform.spinlock); esp_os_exit_critical(&s_platform.spinlock);
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION
gdma_sleep_retention_init(group->group_id, pair_id); gdma_sleep_retention_init(group->group_id, pair_id);
@@ -737,17 +738,17 @@ static esp_err_t gdma_del_tx_channel(gdma_channel_t *dma_channel)
int pair_id = pair->pair_id; int pair_id = pair->pair_id;
int group_id = group->group_id; int group_id = group->group_id;
gdma_tx_channel_t *tx_chan = __containerof(dma_channel, gdma_tx_channel_t, base); gdma_tx_channel_t *tx_chan = __containerof(dma_channel, gdma_tx_channel_t, base);
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
pair->tx_chan = NULL; pair->tx_chan = NULL;
pair->occupy_code &= ~SEARCH_REQUEST_TX_CHANNEL; pair->occupy_code &= ~SEARCH_REQUEST_TX_CHANNEL;
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
if (dma_channel->intr) { if (dma_channel->intr) {
esp_intr_free(dma_channel->intr); esp_intr_free(dma_channel->intr);
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events
gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
ESP_LOGD(TAG, "uninstall interrupt service for tx channel (%d,%d)", group_id, pair_id); ESP_LOGD(TAG, "uninstall interrupt service for tx channel (%d,%d)", group_id, pair_id);
} }
@@ -766,17 +767,17 @@ static esp_err_t gdma_del_rx_channel(gdma_channel_t *dma_channel)
int pair_id = pair->pair_id; int pair_id = pair->pair_id;
int group_id = group->group_id; int group_id = group->group_id;
gdma_rx_channel_t *rx_chan = __containerof(dma_channel, gdma_rx_channel_t, base); gdma_rx_channel_t *rx_chan = __containerof(dma_channel, gdma_rx_channel_t, base);
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
pair->rx_chan = NULL; pair->rx_chan = NULL;
pair->occupy_code &= ~SEARCH_REQUEST_RX_CHANNEL; pair->occupy_code &= ~SEARCH_REQUEST_RX_CHANNEL;
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
if (dma_channel->intr) { if (dma_channel->intr) {
esp_intr_free(dma_channel->intr); esp_intr_free(dma_channel->intr);
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events
gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
ESP_LOGD(TAG, "uninstall interrupt service for rx channel (%d,%d)", group_id, pair_id); ESP_LOGD(TAG, "uninstall interrupt service for rx channel (%d,%d)", group_id, pair_id);
} }
@@ -889,10 +890,10 @@ static esp_err_t gdma_install_rx_interrupt(gdma_rx_channel_t *rx_chan)
ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed"); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed");
rx_chan->base.intr = intr; rx_chan->base.intr = intr;
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events
gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
ESP_LOGD(TAG, "install interrupt service for rx channel (%d,%d)", group->group_id, pair_id); ESP_LOGD(TAG, "install interrupt service for rx channel (%d,%d)", group->group_id, pair_id);
err: err:
@@ -921,10 +922,10 @@ static esp_err_t gdma_install_tx_interrupt(gdma_tx_channel_t *tx_chan)
ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed"); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed");
tx_chan->base.intr = intr; tx_chan->base.intr = intr;
portENTER_CRITICAL(&pair->spinlock); esp_os_enter_critical(&pair->spinlock);
gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events
gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events
portEXIT_CRITICAL(&pair->spinlock); esp_os_exit_critical(&pair->spinlock);
ESP_LOGD(TAG, "install interrupt service for tx channel (%d,%d)", group->group_id, pair_id); ESP_LOGD(TAG, "install interrupt service for tx channel (%d,%d)", group->group_id, pair_id);
err: err:

View File

@@ -19,6 +19,7 @@
#include "esp_rom_caps.h" #include "esp_rom_caps.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "esp_private/critical_section.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "rom/rtc.h" #include "rom/rtc.h"
@@ -38,7 +39,7 @@ extern uint32_t g_ticks_per_us_pro;
// Any code utilizing locks, which depend on FreeRTOS, should be omitted // Any code utilizing locks, which depend on FreeRTOS, should be omitted
// when building for Non-OS environments // when building for Non-OS environments
#if !NON_OS_BUILD #if !NON_OS_BUILD
static portMUX_TYPE s_esp_rtc_time_lock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_esp_rtc_time_lock = portMUX_INITIALIZER_UNLOCKED;
#endif #endif
#if SOC_RTC_MEM_SUPPORTED #if SOC_RTC_MEM_SUPPORTED
@@ -100,7 +101,7 @@ int IRAM_ATTR esp_clk_xtal_freq(void)
#if !NON_OS_BUILD #if !NON_OS_BUILD
uint64_t esp_rtc_get_time_us(void) uint64_t esp_rtc_get_time_us(void)
{ {
portENTER_CRITICAL_SAFE(&s_esp_rtc_time_lock); esp_os_enter_critical_safe(&s_esp_rtc_time_lock);
const uint32_t cal = esp_clk_slowclk_cal_get(); const uint32_t cal = esp_clk_slowclk_cal_get();
#if SOC_RTC_MEM_SUPPORTED #if SOC_RTC_MEM_SUPPORTED
static bool first_call = true; static bool first_call = true;
@@ -143,11 +144,11 @@ uint64_t esp_rtc_get_time_us(void)
s_rtc_timer_retain_mem.rtc_last_ticks = rtc_this_ticks; s_rtc_timer_retain_mem.rtc_last_ticks = rtc_this_ticks;
s_rtc_timer_retain_mem.checksum = calc_checksum(); s_rtc_timer_retain_mem.checksum = calc_checksum();
uint64_t esp_rtc_time_us = s_rtc_timer_retain_mem.rtc_time_us; uint64_t esp_rtc_time_us = s_rtc_timer_retain_mem.rtc_time_us;
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock); esp_os_exit_critical_safe(&s_esp_rtc_time_lock);
return esp_rtc_time_us; return esp_rtc_time_us;
#else #else
uint64_t esp_rtc_time_us = delta_time_us + clk_ll_rtc_slow_load_rtc_fix_us(); uint64_t esp_rtc_time_us = delta_time_us + clk_ll_rtc_slow_load_rtc_fix_us();
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock); esp_os_exit_critical_safe(&s_esp_rtc_time_lock);
return esp_rtc_time_us; return esp_rtc_time_us;
#endif #endif
} }
@@ -162,7 +163,7 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal)
#if SOC_RTC_MEM_SUPPORTED #if SOC_RTC_MEM_SUPPORTED
esp_rtc_get_time_us(); esp_rtc_get_time_us();
#else #else
portENTER_CRITICAL_SAFE(&s_esp_rtc_time_lock); esp_os_enter_critical_safe(&s_esp_rtc_time_lock);
uint32_t old_cal = clk_ll_rtc_slow_load_cal(); uint32_t old_cal = clk_ll_rtc_slow_load_cal();
if (old_cal != 0) { if (old_cal != 0) {
/** /**
@@ -185,7 +186,7 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal)
new_fix_us = old_fix_us - new_fix_us; new_fix_us = old_fix_us - new_fix_us;
clk_ll_rtc_slow_store_rtc_fix_us(new_fix_us); clk_ll_rtc_slow_store_rtc_fix_us(new_fix_us);
} }
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock); esp_os_exit_critical_safe(&s_esp_rtc_time_lock);
#endif // SOC_RTC_MEM_SUPPORTED #endif // SOC_RTC_MEM_SUPPORTED
#endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER #endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
clk_ll_rtc_slow_store_cal(new_cal); clk_ll_rtc_slow_store_cal(new_cal);
@@ -208,11 +209,11 @@ uint64_t esp_clk_rtc_time(void)
#if !NON_OS_BUILD #if !NON_OS_BUILD
void esp_clk_private_lock(void) void esp_clk_private_lock(void)
{ {
portENTER_CRITICAL(&s_esp_rtc_time_lock); esp_os_enter_critical(&s_esp_rtc_time_lock);
} }
void esp_clk_private_unlock(void) void esp_clk_private_unlock(void)
{ {
portEXIT_CRITICAL(&s_esp_rtc_time_lock); esp_os_exit_critical(&s_esp_rtc_time_lock);
} }
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -19,6 +19,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "esp_private/gpio.h" #include "esp_private/gpio.h"
#include "esp_private/critical_section.h"
typedef struct clkout_channel_handle { typedef struct clkout_channel_handle {
bool is_mapped; bool is_mapped;
@@ -40,8 +41,8 @@ typedef struct esp_clock_output_mapping {
static const char *TAG = "esp_clock_output"; static const char *TAG = "esp_clock_output";
static SLIST_HEAD(esp_clock_output_mapping_head, esp_clock_output_mapping) s_mapping_list = SLIST_HEAD_INITIALIZER(s_mapping_list_head); static SLIST_HEAD(esp_clock_output_mapping_head, esp_clock_output_mapping) s_mapping_list = SLIST_HEAD_INITIALIZER(s_mapping_list_head);
static portMUX_TYPE s_mapping_list_lock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_mapping_list_lock = portMUX_INITIALIZER_UNLOCKED;
static portMUX_TYPE s_clkout_lock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_clkout_lock = portMUX_INITIALIZER_UNLOCKED;
static clkout_channel_handle_t s_clkout_handle[CLKOUT_CHANNEL_MAX] = { static clkout_channel_handle_t s_clkout_handle[CLKOUT_CHANNEL_MAX] = {
[0 ... CLKOUT_CHANNEL_MAX - 1] = { [0 ... CLKOUT_CHANNEL_MAX - 1] = {
@@ -61,7 +62,7 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig
if (channel_num < 0) { if (channel_num < 0) {
return NULL; return NULL;
} }
portENTER_CRITICAL(&s_clkout_handle[channel_num].clkout_channel_lock); esp_os_enter_critical(&s_clkout_handle[channel_num].clkout_channel_lock);
if (!s_clkout_handle[channel_num].is_mapped) { if (!s_clkout_handle[channel_num].is_mapped) {
s_clkout_handle[channel_num].is_mapped = true; s_clkout_handle[channel_num].is_mapped = true;
allocated_channel = &s_clkout_handle[channel_num]; allocated_channel = &s_clkout_handle[channel_num];
@@ -72,39 +73,39 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig
if (allocated_channel != NULL) { if (allocated_channel != NULL) {
allocated_channel->channel_id = (clock_out_channel_t)channel_num; allocated_channel->channel_id = (clock_out_channel_t)channel_num;
} }
portEXIT_CRITICAL(&s_clkout_handle[channel_num].clkout_channel_lock); esp_os_exit_critical(&s_clkout_handle[channel_num].clkout_channel_lock);
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) {
portENTER_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); esp_os_enter_critical(&s_clkout_handle[channel].clkout_channel_lock);
if (!s_clkout_handle[channel].is_mapped) { if (!s_clkout_handle[channel].is_mapped) {
s_clkout_handle[channel].is_mapped = true; s_clkout_handle[channel].is_mapped = true;
allocated_channel = &s_clkout_handle[channel]; allocated_channel = &s_clkout_handle[channel];
allocated_channel->channel_id = (clock_out_channel_t)channel; allocated_channel->channel_id = (clock_out_channel_t)channel;
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); esp_os_exit_critical(&s_clkout_handle[channel].clkout_channel_lock);
break; break;
} else if (s_clkout_handle[channel].mapped_clock == clk_sig) { } else if (s_clkout_handle[channel].mapped_clock == clk_sig) {
allocated_channel = &s_clkout_handle[channel]; allocated_channel = &s_clkout_handle[channel];
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); esp_os_exit_critical(&s_clkout_handle[channel].clkout_channel_lock);
break; break;
} }
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); esp_os_exit_critical(&s_clkout_handle[channel].clkout_channel_lock);
} }
#endif #endif
if (allocated_channel != NULL) { if (allocated_channel != NULL) {
portENTER_CRITICAL(&allocated_channel->clkout_channel_lock); esp_os_enter_critical(&allocated_channel->clkout_channel_lock);
allocated_channel->mapped_io_bmap |= BIT(gpio_num); allocated_channel->mapped_io_bmap |= BIT(gpio_num);
allocated_channel->mapped_clock = clk_sig; allocated_channel->mapped_clock = clk_sig;
allocated_channel->ref_cnt++; allocated_channel->ref_cnt++;
if (allocated_channel->ref_cnt == 1) { if (allocated_channel->ref_cnt == 1) {
portENTER_CRITICAL(&s_clkout_lock); esp_os_enter_critical(&s_clkout_lock);
#if SOC_CLOCKOUT_HAS_SOURCE_GATE #if SOC_CLOCKOUT_HAS_SOURCE_GATE
clk_ll_enable_clkout_source(clk_sig, true); clk_ll_enable_clkout_source(clk_sig, true);
#endif #endif
clk_hal_clock_output_setup(clk_sig, allocated_channel->channel_id); clk_hal_clock_output_setup(clk_sig, allocated_channel->channel_id);
portEXIT_CRITICAL(&s_clkout_lock); esp_os_exit_critical(&s_clkout_lock);
} }
portEXIT_CRITICAL(&allocated_channel->clkout_channel_lock); esp_os_exit_critical(&allocated_channel->clkout_channel_lock);
} }
return allocated_channel; return allocated_channel;
@@ -114,14 +115,14 @@ static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t*
{ {
esp_clock_output_mapping_t *allocated_mapping = NULL; esp_clock_output_mapping_t *allocated_mapping = NULL;
portENTER_CRITICAL(&s_mapping_list_lock); esp_os_enter_critical(&s_mapping_list_lock);
esp_clock_output_mapping_t *hdl; esp_clock_output_mapping_t *hdl;
SLIST_FOREACH(hdl, &s_mapping_list, next) { SLIST_FOREACH(hdl, &s_mapping_list, next) {
if ((hdl->clkout_channel_hdl == channel_hdl) && (hdl->mapped_io == gpio_num)) { if ((hdl->clkout_channel_hdl == channel_hdl) && (hdl->mapped_io == gpio_num)) {
allocated_mapping = hdl; allocated_mapping = hdl;
} }
} }
portEXIT_CRITICAL(&s_mapping_list_lock); esp_os_exit_critical(&s_mapping_list_lock);
if (allocated_mapping == NULL) { if (allocated_mapping == NULL) {
allocated_mapping = (esp_clock_output_mapping_t *)malloc(sizeof(esp_clock_output_mapping_t)); allocated_mapping = (esp_clock_output_mapping_t *)malloc(sizeof(esp_clock_output_mapping_t));
@@ -132,12 +133,12 @@ static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t*
allocated_mapping->clkout_channel_hdl = channel_hdl; allocated_mapping->clkout_channel_hdl = channel_hdl;
allocated_mapping->ref_cnt = 0; allocated_mapping->ref_cnt = 0;
portMUX_INITIALIZE(&allocated_mapping->clkout_mapping_lock); portMUX_INITIALIZE(&allocated_mapping->clkout_mapping_lock);
portENTER_CRITICAL(&s_mapping_list_lock); esp_os_enter_critical(&s_mapping_list_lock);
SLIST_INSERT_HEAD(&s_mapping_list, allocated_mapping, next); SLIST_INSERT_HEAD(&s_mapping_list, allocated_mapping, next);
portEXIT_CRITICAL(&s_mapping_list_lock); esp_os_exit_critical(&s_mapping_list_lock);
} }
portENTER_CRITICAL(&allocated_mapping->clkout_mapping_lock); esp_os_enter_critical(&allocated_mapping->clkout_mapping_lock);
allocated_mapping->ref_cnt++; allocated_mapping->ref_cnt++;
if (allocated_mapping->ref_cnt == 1) { if (allocated_mapping->ref_cnt == 1) {
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX #if SOC_GPIO_CLOCKOUT_BY_IO_MUX
@@ -148,44 +149,44 @@ static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t*
esp_rom_gpio_connect_out_signal(gpio_num, CLKOUT_CHANNEL_TO_GPIO_SIG_ID(allocated_mapping->clkout_channel_hdl->channel_id), false, false); esp_rom_gpio_connect_out_signal(gpio_num, CLKOUT_CHANNEL_TO_GPIO_SIG_ID(allocated_mapping->clkout_channel_hdl->channel_id), false, false);
#endif #endif
} }
portEXIT_CRITICAL(&allocated_mapping->clkout_mapping_lock); esp_os_exit_critical(&allocated_mapping->clkout_mapping_lock);
return allocated_mapping; return allocated_mapping;
} }
static void clkout_channel_free(clkout_channel_handle_t *channel_hdl) static void clkout_channel_free(clkout_channel_handle_t *channel_hdl)
{ {
portENTER_CRITICAL(&channel_hdl->clkout_channel_lock); esp_os_enter_critical(&channel_hdl->clkout_channel_lock);
if (--channel_hdl->ref_cnt == 0) { if (--channel_hdl->ref_cnt == 0) {
portENTER_CRITICAL(&s_clkout_lock); esp_os_enter_critical(&s_clkout_lock);
#if SOC_CLOCKOUT_HAS_SOURCE_GATE #if SOC_CLOCKOUT_HAS_SOURCE_GATE
clk_ll_enable_clkout_source(channel_hdl->mapped_clock, false); clk_ll_enable_clkout_source(channel_hdl->mapped_clock, false);
#endif #endif
clk_hal_clock_output_teardown(channel_hdl->channel_id); clk_hal_clock_output_teardown(channel_hdl->channel_id);
portEXIT_CRITICAL(&s_clkout_lock); esp_os_exit_critical(&s_clkout_lock);
channel_hdl->mapped_clock = CLKOUT_SIG_INVALID; channel_hdl->mapped_clock = CLKOUT_SIG_INVALID;
channel_hdl->is_mapped = false; channel_hdl->is_mapped = false;
} }
portEXIT_CRITICAL(&channel_hdl->clkout_channel_lock); esp_os_exit_critical(&channel_hdl->clkout_channel_lock);
} }
static void clkout_mapping_free(esp_clock_output_mapping_t *mapping_hdl) static void clkout_mapping_free(esp_clock_output_mapping_t *mapping_hdl)
{ {
portENTER_CRITICAL(&mapping_hdl->clkout_mapping_lock); esp_os_enter_critical(&mapping_hdl->clkout_mapping_lock);
clkout_channel_free(mapping_hdl->clkout_channel_hdl); clkout_channel_free(mapping_hdl->clkout_channel_hdl);
bool do_free_mapping_hdl = false; bool do_free_mapping_hdl = false;
if (--mapping_hdl->ref_cnt == 0) { if (--mapping_hdl->ref_cnt == 0) {
gpio_output_disable(mapping_hdl->mapped_io); gpio_output_disable(mapping_hdl->mapped_io);
portENTER_CRITICAL(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock); esp_os_enter_critical(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock);
mapping_hdl->clkout_channel_hdl->mapped_io_bmap &= ~BIT(mapping_hdl->mapped_io); mapping_hdl->clkout_channel_hdl->mapped_io_bmap &= ~BIT(mapping_hdl->mapped_io);
portEXIT_CRITICAL(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock); esp_os_exit_critical(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock);
portENTER_CRITICAL(&s_mapping_list_lock); esp_os_enter_critical(&s_mapping_list_lock);
SLIST_REMOVE(&s_mapping_list, mapping_hdl, esp_clock_output_mapping, next); SLIST_REMOVE(&s_mapping_list, mapping_hdl, esp_clock_output_mapping, next);
portEXIT_CRITICAL(&s_mapping_list_lock); esp_os_exit_critical(&s_mapping_list_lock);
do_free_mapping_hdl = true; do_free_mapping_hdl = true;
} }
portEXIT_CRITICAL(&mapping_hdl->clkout_mapping_lock); esp_os_exit_critical(&mapping_hdl->clkout_mapping_lock);
if (do_free_mapping_hdl) { if (do_free_mapping_hdl) {
free(mapping_hdl); free(mapping_hdl);
@@ -231,9 +232,9 @@ esp_err_t esp_clock_output_set_divider(esp_clock_output_mapping_handle_t clkout_
{ {
ESP_RETURN_ON_FALSE(((div_num > 0) && (div_num <= 256)), ESP_ERR_INVALID_ARG, TAG, "Divider number must be in the range of [1, 256]"); ESP_RETURN_ON_FALSE(((div_num > 0) && (div_num <= 256)), ESP_ERR_INVALID_ARG, TAG, "Divider number must be in the range of [1, 256]");
ESP_RETURN_ON_FALSE((clkout_mapping_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid"); ESP_RETURN_ON_FALSE((clkout_mapping_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid");
portENTER_CRITICAL(&clkout_mapping_hdl->clkout_mapping_lock); esp_os_enter_critical(&clkout_mapping_hdl->clkout_mapping_lock);
clk_hal_clock_output_set_divider(clkout_mapping_hdl->clkout_channel_hdl->channel_id, div_num); clk_hal_clock_output_set_divider(clkout_mapping_hdl->clkout_channel_hdl->channel_id, div_num);
portEXIT_CRITICAL(&clkout_mapping_hdl->clkout_mapping_lock); esp_os_exit_critical(&clkout_mapping_hdl->clkout_mapping_lock);
return ESP_OK; return ESP_OK;
} }
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -26,6 +26,7 @@
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/etm_interface.h" #include "esp_private/etm_interface.h"
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
#include "esp_private/critical_section.h"
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
@@ -195,7 +196,7 @@ static esp_err_t etm_chan_register_to_group(esp_etm_channel_t *chan)
group = etm_acquire_group_handle(i); group = etm_acquire_group_handle(i);
ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no mem for group (%d)", i); ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no mem for group (%d)", i);
// loop to search free channel in the group // loop to search free channel in the group
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
for (int j = 0; j < SOC_ETM_CHANNELS_PER_GROUP; j++) { for (int j = 0; j < SOC_ETM_CHANNELS_PER_GROUP; j++) {
if (!group->chans[j]) { if (!group->chans[j]) {
chan_id = j; chan_id = j;
@@ -203,7 +204,7 @@ static esp_err_t etm_chan_register_to_group(esp_etm_channel_t *chan)
break; break;
} }
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
if (chan_id < 0) { if (chan_id < 0) {
etm_release_group_handle(group); etm_release_group_handle(group);
group = NULL; group = NULL;
@@ -221,9 +222,9 @@ static void etm_chan_unregister_from_group(esp_etm_channel_t *chan)
{ {
etm_group_t *group = chan->group; etm_group_t *group = chan->group;
int chan_id = chan->chan_id; int chan_id = chan->chan_id;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
group->chans[chan_id] = NULL; group->chans[chan_id] = NULL;
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
// channel has a reference on group, release it now // channel has a reference on group, release it now
etm_release_group_handle(group); etm_release_group_handle(group);
} }
@@ -362,7 +363,7 @@ esp_err_t esp_etm_dump(FILE *out_stream)
etm_hal_context_t *hal = &group->hal; etm_hal_context_t *hal = &group->hal;
for (int j = 0; j < SOC_ETM_CHANNELS_PER_GROUP; j++) { for (int j = 0; j < SOC_ETM_CHANNELS_PER_GROUP; j++) {
bool print_line = true; bool print_line = true;
portENTER_CRITICAL(&group->spinlock); esp_os_enter_critical(&group->spinlock);
etm_chan = group->chans[j]; etm_chan = group->chans[j];
if (etm_ll_is_channel_enabled(hal->regs, j)) { if (etm_ll_is_channel_enabled(hal->regs, j)) {
if (!etm_chan) { if (!etm_chan) {
@@ -383,7 +384,7 @@ esp_err_t esp_etm_dump(FILE *out_stream)
print_line = false; print_line = false;
} }
} }
portEXIT_CRITICAL(&group->spinlock); esp_os_exit_critical(&group->spinlock);
if (print_line) { if (print_line) {
fputs(line, out_stream); fputs(line, out_stream);
} }

View File

@@ -22,6 +22,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_cpu.h" #include "esp_cpu.h"
#include "esp_private/rtc_ctrl.h" #include "esp_private/rtc_ctrl.h"
#include "esp_private/critical_section.h"
#include "soc/interrupts.h" #include "soc/interrupts.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@@ -125,7 +126,7 @@ static uint32_t non_iram_int_mask[SOC_CPU_CORES_NUM];
static uint32_t non_iram_int_disabled[SOC_CPU_CORES_NUM]; static uint32_t non_iram_int_disabled[SOC_CPU_CORES_NUM];
static bool non_iram_int_disabled_flag[SOC_CPU_CORES_NUM]; static bool non_iram_int_disabled_flag[SOC_CPU_CORES_NUM];
static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) spinlock = portMUX_INITIALIZER_UNLOCKED;
//Inserts an item into vector_desc list so that the list is sorted //Inserts an item into vector_desc list so that the list is sorted
//with an incrementing cpu.intno value. //with an incrementing cpu.intno value.
@@ -222,17 +223,17 @@ esp_err_t esp_intr_mark_shared(int intno, int cpu, bool is_int_ram)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL(&spinlock); esp_os_enter_critical(&spinlock);
vector_desc_t *vd = get_desc_for_int(intno, cpu); vector_desc_t *vd = get_desc_for_int(intno, cpu);
if (vd == NULL) { if (vd == NULL) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
vd->flags = (vd->flags & ~VECDESC_FL_TYPE_MASK) | VECDESC_FL_SHARED; vd->flags = (vd->flags & ~VECDESC_FL_TYPE_MASK) | VECDESC_FL_SHARED;
if (is_int_ram) { if (is_int_ram) {
vd->flags |= VECDESC_FL_INIRAM; vd->flags |= VECDESC_FL_INIRAM;
} }
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -246,14 +247,14 @@ esp_err_t esp_intr_reserve(int intno, int cpu)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL(&spinlock); esp_os_enter_critical(&spinlock);
vector_desc_t *vd = get_desc_for_int(intno, cpu); vector_desc_t *vd = get_desc_for_int(intno, cpu);
if (vd == NULL) { if (vd == NULL) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
vd->flags = VECDESC_FL_RESERVED; vd->flags = VECDESC_FL_RESERVED;
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -463,7 +464,7 @@ static void ESP_INTR_IRAM_ATTR shared_intr_isr(void *arg)
{ {
vector_desc_t *vd = (vector_desc_t*)arg; vector_desc_t *vd = (vector_desc_t*)arg;
shared_vector_desc_t *sh_vec = vd->shared_vec_info; shared_vector_desc_t *sh_vec = vd->shared_vec_info;
portENTER_CRITICAL_ISR(&spinlock); esp_os_enter_critical_isr(&spinlock);
while(sh_vec) { while(sh_vec) {
if (!sh_vec->disabled) { if (!sh_vec->disabled) {
if ((sh_vec->statusreg == NULL) || (*sh_vec->statusreg & sh_vec->statusmask)) { if ((sh_vec->statusreg == NULL) || (*sh_vec->statusreg & sh_vec->statusmask)) {
@@ -477,7 +478,7 @@ static void ESP_INTR_IRAM_ATTR shared_intr_isr(void *arg)
} }
sh_vec = sh_vec->next; sh_vec = sh_vec->next;
} }
portEXIT_CRITICAL_ISR(&spinlock); esp_os_exit_critical_isr(&spinlock);
} }
#if CONFIG_APPTRACE_SV_ENABLE #if CONFIG_APPTRACE_SV_ENABLE
@@ -485,7 +486,7 @@ static void ESP_INTR_IRAM_ATTR shared_intr_isr(void *arg)
static void ESP_INTR_IRAM_ATTR non_shared_intr_isr(void *arg) static void ESP_INTR_IRAM_ATTR non_shared_intr_isr(void *arg)
{ {
non_shared_isr_arg_t *ns_isr_arg = (non_shared_isr_arg_t*)arg; non_shared_isr_arg_t *ns_isr_arg = (non_shared_isr_arg_t*)arg;
portENTER_CRITICAL_ISR(&spinlock); esp_os_enter_critical_isr(&spinlock);
traceISR_ENTER(ns_isr_arg->source + ETS_INTERNAL_INTR_SOURCE_OFF); traceISR_ENTER(ns_isr_arg->source + ETS_INTERNAL_INTR_SOURCE_OFF);
// FIXME: can we call ISR and check os_task_switch_is_pended() after releasing spinlock? // FIXME: can we call ISR and check os_task_switch_is_pended() after releasing spinlock?
// when CONFIG_APPTRACE_SV_ENABLE = 0 ISRs for non-shared IRQs are called without spinlock // when CONFIG_APPTRACE_SV_ENABLE = 0 ISRs for non-shared IRQs are called without spinlock
@@ -494,7 +495,7 @@ static void ESP_INTR_IRAM_ATTR non_shared_intr_isr(void *arg)
if (!os_task_switch_is_pended(esp_cpu_get_core_id())) { if (!os_task_switch_is_pended(esp_cpu_get_core_id())) {
traceISR_EXIT(); traceISR_EXIT();
} }
portEXIT_CRITICAL_ISR(&spinlock); esp_os_exit_critical_isr(&spinlock);
} }
#endif #endif
@@ -576,12 +577,12 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
portENTER_CRITICAL(&spinlock); esp_os_enter_critical(&spinlock);
uint32_t cpu = esp_cpu_get_core_id(); uint32_t cpu = esp_cpu_get_core_id();
if (shared_handle != NULL) { if (shared_handle != NULL) {
/* Sanity check, should not occur */ /* Sanity check, should not occur */
if (shared_handle->vector_desc == NULL) { if (shared_handle->vector_desc == NULL) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
/* If a shared vector was given, force the current interrupt source to same CPU interrupt line */ /* If a shared vector was given, force the current interrupt source to same CPU interrupt line */
@@ -592,7 +593,7 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
int intr = get_available_int(flags, cpu, force, source); int intr = get_available_int(flags, cpu, force, source);
if (intr == -1) { if (intr == -1) {
//None found. Bail out. //None found. Bail out.
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
free(ret); free(ret);
ESP_LOGE(TAG, "No free interrupt inputs for %s interrupt (flags 0x%X)", esp_isr_names[source], flags); ESP_LOGE(TAG, "No free interrupt inputs for %s interrupt (flags 0x%X)", esp_isr_names[source], flags);
return ESP_ERR_NOT_FOUND; return ESP_ERR_NOT_FOUND;
@@ -600,7 +601,7 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
//Get an int vector desc for int. //Get an int vector desc for int.
vector_desc_t *vd = get_desc_for_int(intr, cpu); vector_desc_t *vd = get_desc_for_int(intr, cpu);
if (vd == NULL) { if (vd == NULL) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
free(ret); free(ret);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@@ -610,7 +611,7 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
//Populate vector entry and add to linked list. //Populate vector entry and add to linked list.
shared_vector_desc_t *sh_vec = heap_caps_malloc(sizeof(shared_vector_desc_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); shared_vector_desc_t *sh_vec = heap_caps_malloc(sizeof(shared_vector_desc_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (sh_vec == NULL) { if (sh_vec == NULL) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
free(ret); free(ret);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@@ -633,7 +634,7 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
#if CONFIG_APPTRACE_SV_ENABLE #if CONFIG_APPTRACE_SV_ENABLE
non_shared_isr_arg_t *ns_isr_arg = heap_caps_malloc(sizeof(non_shared_isr_arg_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); non_shared_isr_arg_t *ns_isr_arg = heap_caps_malloc(sizeof(non_shared_isr_arg_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!ns_isr_arg) { if (!ns_isr_arg) {
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
free(ret); free(ret);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@@ -698,7 +699,7 @@ esp_err_t esp_intr_alloc_intrstatus_bind(int source, int flags, uint32_t intrsta
#endif #endif
#endif #endif
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
//Fill return handle if needed, otherwise free handle. //Fill return handle if needed, otherwise free handle.
if (ret_handle != NULL) { if (ret_handle != NULL) {
@@ -744,7 +745,7 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_
if (vd->flags & VECDESC_FL_SHARED) { if (vd->flags & VECDESC_FL_SHARED) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL(&spinlock); esp_os_enter_critical(&spinlock);
uint32_t mask = (1 << vd->intno); uint32_t mask = (1 << vd->intno);
if (is_in_iram) { if (is_in_iram) {
vd->flags |= VECDESC_FL_INIRAM; vd->flags |= VECDESC_FL_INIRAM;
@@ -753,7 +754,7 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_
vd->flags &= ~VECDESC_FL_INIRAM; vd->flags &= ~VECDESC_FL_INIRAM;
non_iram_int_mask[vd->cpu] |= mask; non_iram_int_mask[vd->cpu] |= mask;
} }
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -797,7 +798,7 @@ static esp_err_t intr_free_for_current_cpu(intr_handle_t handle)
{ {
bool free_shared_vector = false; bool free_shared_vector = false;
portENTER_CRITICAL(&spinlock); esp_os_enter_critical(&spinlock);
esp_intr_disable(handle); esp_intr_disable(handle);
if (handle->vector_desc->flags & VECDESC_FL_SHARED) { if (handle->vector_desc->flags & VECDESC_FL_SHARED) {
//Find and kill the shared int //Find and kill the shared int
@@ -853,7 +854,7 @@ static esp_err_t intr_free_for_current_cpu(intr_handle_t handle)
//Also kill non_iram mask bit. //Also kill non_iram mask bit.
non_iram_int_mask[handle->vector_desc->cpu] &= ~(1<<(handle->vector_desc->intno)); non_iram_int_mask[handle->vector_desc->cpu] &= ~(1<<(handle->vector_desc->intno));
} }
portEXIT_CRITICAL(&spinlock); esp_os_exit_critical(&spinlock);
free(handle); free(handle);
return ESP_OK; return ESP_OK;
} }
@@ -890,7 +891,7 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_enable(intr_handle_t handle)
if (!handle) { if (!handle) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&spinlock); esp_os_enter_critical_safe(&spinlock);
int source; int source;
if (handle->shared_vector_desc) { if (handle->shared_vector_desc) {
handle->shared_vector_desc->disabled = 0; handle->shared_vector_desc->disabled = 0;
@@ -904,12 +905,12 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_enable(intr_handle_t handle)
} else { } else {
//Re-enable using cpu int ena reg //Re-enable using cpu int ena reg
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) { if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu
} }
ESP_INTR_ENABLE(handle->vector_desc->intno); ESP_INTR_ENABLE(handle->vector_desc->intno);
} }
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
return ESP_OK; return ESP_OK;
} }
@@ -919,7 +920,7 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_disable(intr_handle_t handle)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&spinlock); esp_os_enter_critical_safe(&spinlock);
int source; int source;
bool disabled = true; bool disabled = true;
if (handle->shared_vector_desc) { if (handle->shared_vector_desc) {
@@ -947,18 +948,18 @@ esp_err_t ESP_INTR_IRAM_ATTR esp_intr_disable(intr_handle_t handle)
} else { } else {
//Disable using per-cpu regs //Disable using per-cpu regs
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) { if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu
} }
ESP_INTR_DISABLE(handle->vector_desc->intno); ESP_INTR_DISABLE(handle->vector_desc->intno);
} }
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
return ESP_OK; return ESP_OK;
} }
void ESP_INTR_IRAM_ATTR esp_intr_noniram_disable(void) void ESP_INTR_IRAM_ATTR esp_intr_noniram_disable(void)
{ {
portENTER_CRITICAL_SAFE(&spinlock); esp_os_enter_critical_safe(&spinlock);
uint32_t oldint; uint32_t oldint;
uint32_t cpu = esp_cpu_get_core_id(); uint32_t cpu = esp_cpu_get_core_id();
uint32_t non_iram_ints = non_iram_int_mask[cpu]; uint32_t non_iram_ints = non_iram_int_mask[cpu];
@@ -972,12 +973,12 @@ void ESP_INTR_IRAM_ATTR esp_intr_noniram_disable(void)
rtc_isr_noniram_disable(cpu); rtc_isr_noniram_disable(cpu);
// Save disabled ints // Save disabled ints
non_iram_int_disabled[cpu] = oldint & non_iram_ints; non_iram_int_disabled[cpu] = oldint & non_iram_ints;
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
} }
void ESP_INTR_IRAM_ATTR esp_intr_noniram_enable(void) void ESP_INTR_IRAM_ATTR esp_intr_noniram_enable(void)
{ {
portENTER_CRITICAL_SAFE(&spinlock); esp_os_enter_critical_safe(&spinlock);
uint32_t cpu = esp_cpu_get_core_id(); uint32_t cpu = esp_cpu_get_core_id();
int non_iram_ints = non_iram_int_disabled[cpu]; int non_iram_ints = non_iram_int_disabled[cpu];
if (!non_iram_int_disabled_flag[cpu]) { if (!non_iram_int_disabled_flag[cpu]) {
@@ -986,7 +987,7 @@ void ESP_INTR_IRAM_ATTR esp_intr_noniram_enable(void)
non_iram_int_disabled_flag[cpu] = false; non_iram_int_disabled_flag[cpu] = false;
esp_cpu_intr_enable(non_iram_ints); esp_cpu_intr_enable(non_iram_ints);
rtc_isr_noniram_enable(cpu); rtc_isr_noniram_enable(cpu);
portEXIT_CRITICAL_SAFE(&spinlock); esp_os_exit_critical_safe(&spinlock);
} }
//These functions are provided in ROM, but the ROM-based functions use non-multicore-capable //These functions are provided in ROM, but the ROM-based functions use non-multicore-capable

View File

@@ -14,6 +14,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/ldo_ll.h" #include "hal/ldo_ll.h"
#include "esp_ldo_regulator.h" #include "esp_ldo_regulator.h"
#include "esp_private/critical_section.h"
static const char *TAG = "ldo"; static const char *TAG = "ldo";
@@ -55,7 +56,7 @@ esp_err_t esp_ldo_acquire_channel(const esp_ldo_channel_config_t *config, esp_ld
bool check_adjustable_constraint_valid = true; bool check_adjustable_constraint_valid = true;
bool check_voltage_constraint_valid = true; bool check_voltage_constraint_valid = true;
portENTER_CRITICAL(&s_spinlock); esp_os_enter_critical(&s_spinlock);
if (config->flags.adjustable) { if (config->flags.adjustable) {
// the user wants to adjust it // the user wants to adjust it
// but the channel is marked as not adjustable // but the channel is marked as not adjustable
@@ -101,7 +102,7 @@ esp_err_t esp_ldo_acquire_channel(const esp_ldo_channel_config_t *config, esp_ld
channel->flags.adjustable = config->flags.adjustable; channel->flags.adjustable = config->flags.adjustable;
channel->chan_id = config->chan_id; channel->chan_id = config->chan_id;
} }
portEXIT_CRITICAL(&s_spinlock); esp_os_exit_critical(&s_spinlock);
ESP_RETURN_ON_FALSE(check_voltage_constraint_valid, ESP_ERR_INVALID_ARG, TAG, ESP_RETURN_ON_FALSE(check_voltage_constraint_valid, ESP_ERR_INVALID_ARG, TAG,
"can't change the voltage for a non-adjustable channel, expect:%dmV, current:%dmV", "can't change the voltage for a non-adjustable channel, expect:%dmV, current:%dmV",
@@ -121,7 +122,7 @@ esp_err_t esp_ldo_release_channel(esp_ldo_channel_handle_t chan)
int unit_id = LDO_ID2UNIT(chan->chan_id); int unit_id = LDO_ID2UNIT(chan->chan_id);
bool is_valid_state = true; bool is_valid_state = true;
portENTER_CRITICAL(&s_spinlock); esp_os_enter_critical(&s_spinlock);
if (chan->ref_cnt <= 0) { if (chan->ref_cnt <= 0) {
is_valid_state = false; is_valid_state = false;
} else { } else {
@@ -135,7 +136,7 @@ esp_err_t esp_ldo_release_channel(esp_ldo_channel_handle_t chan)
chan->chan_id = -1; chan->chan_id = -1;
} }
} }
portEXIT_CRITICAL(&s_spinlock); esp_os_exit_critical(&s_spinlock);
ESP_RETURN_ON_FALSE(is_valid_state, ESP_ERR_INVALID_STATE, TAG, "LDO channel released too many times"); ESP_RETURN_ON_FALSE(is_valid_state, ESP_ERR_INVALID_STATE, TAG, "LDO channel released too many times");

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -9,6 +9,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/mipi_csi_share_hw_ctrl.h" #include "esp_private/mipi_csi_share_hw_ctrl.h"
#include "esp_private/critical_section.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/mipi_csi_ll.h" #include "hal/mipi_csi_ll.h"
@@ -31,7 +32,7 @@ static const char *TAG = "CSI_SHARE";
esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id) esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id)
{ {
bool found = true; bool found = true;
portENTER_CRITICAL(&s_ctx.spinlock); esp_os_enter_critical(&s_ctx.spinlock);
for (int i = 0; i < MIPI_CSI_BRG_LL_BRG_NUMS; i ++) { for (int i = 0; i < MIPI_CSI_BRG_LL_BRG_NUMS; i ++) {
bool user_is_shared = (s_ctx.user[i] == MIPI_CSI_BRG_USER_SHARE); bool user_is_shared = (s_ctx.user[i] == MIPI_CSI_BRG_USER_SHARE);
bool to_share = (user == MIPI_CSI_BRG_USER_SHARE); bool to_share = (user == MIPI_CSI_BRG_USER_SHARE);
@@ -60,7 +61,7 @@ esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id)
break; break;
} }
} }
portEXIT_CRITICAL(&s_ctx.spinlock); esp_os_exit_critical(&s_ctx.spinlock);
if (!found) { if (!found) {
return ESP_ERR_NOT_FOUND; return ESP_ERR_NOT_FOUND;
@@ -70,12 +71,12 @@ esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id)
esp_err_t mipi_csi_brg_declaim(int id) esp_err_t mipi_csi_brg_declaim(int id)
{ {
portENTER_CRITICAL(&s_ctx.spinlock); esp_os_enter_critical(&s_ctx.spinlock);
s_ctx.ref_cnt[id]--; s_ctx.ref_cnt[id]--;
if (s_ctx.ref_cnt[id] < 0) { if (s_ctx.ref_cnt[id] < 0) {
s_ctx.ref_cnt[id] = 0; s_ctx.ref_cnt[id] = 0;
portEXIT_CRITICAL(&s_ctx.spinlock); esp_os_exit_critical(&s_ctx.spinlock);
ESP_LOGE(TAG, "%s called, but s_ctx.ref_cnt[%d] == 0", __func__, id); ESP_LOGE(TAG, "%s called, but s_ctx.ref_cnt[%d] == 0", __func__, id);
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} else if (s_ctx.ref_cnt[id] == 0) { } else if (s_ctx.ref_cnt[id] == 0) {
@@ -85,7 +86,7 @@ esp_err_t mipi_csi_brg_declaim(int id)
} }
s_ctx.user[id] = MIPI_CSI_BRG_USER_NO_USER; s_ctx.user[id] = MIPI_CSI_BRG_USER_NO_USER;
} }
portEXIT_CRITICAL(&s_ctx.spinlock); esp_os_exit_critical(&s_ctx.spinlock);
return ESP_OK; return ESP_OK;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -15,6 +15,7 @@
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_pmu.h" #include "esp_private/esp_pmu.h"
#include "esp_private/critical_section.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
@@ -187,10 +188,10 @@ esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain);
modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code & ~BIT(mode))); modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code & ~BIT(mode)));
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_exit_critical_safe(&MODEM_CLOCK_instance()->lock);
return ESP_OK; return ESP_OK;
} }
@@ -203,10 +204,10 @@ esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_h
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain);
modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code | BIT(mode))); modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code | BIT(mode)));
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_exit_critical_safe(&MODEM_CLOCK_instance()->lock);
return ESP_OK; return ESP_OK;
} }
#endif // #if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND #endif // #if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
@@ -214,7 +215,7 @@ esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_h
static void IRAM_ATTR modem_clock_device_enable(modem_clock_context_t *ctx, uint32_t dev_map) static void IRAM_ATTR modem_clock_device_enable(modem_clock_context_t *ctx, uint32_t dev_map)
{ {
int16_t refs = 0; int16_t refs = 0;
portENTER_CRITICAL_SAFE(&ctx->lock); esp_os_enter_critical_safe(&ctx->lock);
for (int i = 0; dev_map; dev_map >>= 1, i++) { for (int i = 0; dev_map; dev_map >>= 1, i++) {
if (dev_map & BIT(0)) { if (dev_map & BIT(0)) {
refs = ctx->dev[i].refs++; refs = ctx->dev[i].refs++;
@@ -223,14 +224,14 @@ static void IRAM_ATTR modem_clock_device_enable(modem_clock_context_t *ctx, uint
} }
} }
} }
portEXIT_CRITICAL_SAFE(&ctx->lock); esp_os_exit_critical_safe(&ctx->lock);
assert(refs >= 0); assert(refs >= 0);
} }
static void IRAM_ATTR modem_clock_device_disable(modem_clock_context_t *ctx, uint32_t dev_map) static void IRAM_ATTR modem_clock_device_disable(modem_clock_context_t *ctx, uint32_t dev_map)
{ {
int16_t refs = 0; int16_t refs = 0;
portENTER_CRITICAL_SAFE(&ctx->lock); esp_os_enter_critical_safe(&ctx->lock);
for (int i = 0; dev_map; dev_map >>= 1, i++) { for (int i = 0; dev_map; dev_map >>= 1, i++) {
if (dev_map & BIT(0)) { if (dev_map & BIT(0)) {
refs = --ctx->dev[i].refs; refs = --ctx->dev[i].refs;
@@ -239,14 +240,14 @@ static void IRAM_ATTR modem_clock_device_disable(modem_clock_context_t *ctx, uin
} }
} }
} }
portEXIT_CRITICAL_SAFE(&ctx->lock); esp_os_exit_critical_safe(&ctx->lock);
assert(refs >= 0); assert(refs >= 0);
} }
void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module) void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module)
{ {
modem_clock_context_t *ctx = MODEM_CLOCK_instance(); __attribute__((unused)) modem_clock_context_t *ctx = MODEM_CLOCK_instance();
portENTER_CRITICAL_SAFE(&ctx->lock); esp_os_enter_critical_safe(&ctx->lock);
switch (module) switch (module)
{ {
#if SOC_WIFI_SUPPORTED #if SOC_WIFI_SUPPORTED
@@ -271,7 +272,7 @@ void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module)
default: default:
assert(0); assert(0);
} }
portEXIT_CRITICAL_SAFE(&ctx->lock); esp_os_exit_critical_safe(&ctx->lock);
} }
#define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST)) #define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST))
@@ -335,12 +336,12 @@ static const DRAM_ATTR uint32_t initial_gating_mode[MODEM_CLOCK_DOMAIN_MAX] = {
#if !CONFIG_IDF_TARGET_ESP32H2 //TODO: PM-92 #if !CONFIG_IDF_TARGET_ESP32H2 //TODO: PM-92
static IRAM_ATTR void modem_clock_module_icg_map_init_all(void) static IRAM_ATTR void modem_clock_module_icg_map_init_all(void)
{ {
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
for (int domain = 0; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) { for (int domain = 0; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) {
uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain);
modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, initial_gating_mode[domain] | code); modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, initial_gating_mode[domain] | code);
} }
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_exit_critical_safe(&MODEM_CLOCK_instance()->lock);
} }
#endif #endif
@@ -375,7 +376,7 @@ void modem_clock_deselect_all_module_lp_clock_source(void)
void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpclk_src_t src, uint32_t divider) void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpclk_src_t src, uint32_t divider)
{ {
assert(IS_MODEM_MODULE(module)); assert(IS_MODEM_MODULE(module));
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
switch (module) switch (module)
{ {
#if SOC_WIFI_SUPPORTED #if SOC_WIFI_SUPPORTED
@@ -439,7 +440,7 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
#endif #endif
MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = src; MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = src;
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_exit_critical_safe(&MODEM_CLOCK_instance()->lock);
#if SOC_LIGHT_SLEEP_SUPPORTED #if SOC_LIGHT_SLEEP_SUPPORTED
/* The power domain of the low-power clock source required by the modem /* The power domain of the low-power clock source required by the modem
@@ -468,7 +469,7 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
void modem_clock_deselect_lp_clock_source(periph_module_t module) void modem_clock_deselect_lp_clock_source(periph_module_t module)
{ {
assert(IS_MODEM_MODULE(module)); assert(IS_MODEM_MODULE(module));
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
#if SOC_LIGHT_SLEEP_SUPPORTED #if SOC_LIGHT_SLEEP_SUPPORTED
modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
#endif #endif
@@ -504,7 +505,7 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
default: default:
break; break;
} }
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); esp_os_exit_critical_safe(&MODEM_CLOCK_instance()->lock);
#if SOC_LIGHT_SLEEP_SUPPORTED #if SOC_LIGHT_SLEEP_SUPPORTED
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) (

View File

@@ -1,11 +1,12 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#ifdef __PERIPH_CTRL_ALLOW_LEGACY_API #ifdef __PERIPH_CTRL_ALLOW_LEGACY_API
#include "hal/clk_gate_ll.h" #include "hal/clk_gate_ll.h"
@@ -17,18 +18,18 @@
/// @brief For simplicity and backward compatible, we are using the same spin lock for both bus clock on/off and reset /// @brief For simplicity and backward compatible, we are using the same spin lock for both bus clock on/off and reset
/// @note We may want to split them into two spin locks in the future /// @note We may want to split them into two spin locks in the future
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0}; static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0};
void periph_rcc_enter(void) void periph_rcc_enter(void)
{ {
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
} }
void periph_rcc_exit(void) void periph_rcc_exit(void)
{ {
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
} }
uint8_t periph_rcc_acquire_enter(periph_module_t periph) uint8_t periph_rcc_acquire_enter(periph_module_t periph)
@@ -59,12 +60,12 @@ void periph_module_enable(periph_module_t periph)
{ {
#ifdef __PERIPH_CTRL_ALLOW_LEGACY_API #ifdef __PERIPH_CTRL_ALLOW_LEGACY_API
assert(periph < PERIPH_MODULE_MAX); assert(periph < PERIPH_MODULE_MAX);
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
if (ref_counts[periph] == 0) { if (ref_counts[periph] == 0) {
periph_ll_enable_clk_clear_rst(periph); periph_ll_enable_clk_clear_rst(periph);
} }
ref_counts[periph]++; ref_counts[periph]++;
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
@@ -72,12 +73,12 @@ void periph_module_disable(periph_module_t periph)
{ {
#ifdef __PERIPH_CTRL_ALLOW_LEGACY_API #ifdef __PERIPH_CTRL_ALLOW_LEGACY_API
assert(periph < PERIPH_MODULE_MAX); assert(periph < PERIPH_MODULE_MAX);
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
ref_counts[periph]--; ref_counts[periph]--;
if (ref_counts[periph] == 0) { if (ref_counts[periph] == 0) {
periph_ll_disable_clk_set_rst(periph); periph_ll_disable_clk_set_rst(periph);
} }
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
@@ -85,9 +86,9 @@ void periph_module_reset(periph_module_t periph)
{ {
#ifdef __PERIPH_CTRL_ALLOW_LEGACY_API #ifdef __PERIPH_CTRL_ALLOW_LEGACY_API
assert(periph < PERIPH_MODULE_MAX); assert(periph < PERIPH_MODULE_MAX);
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
periph_ll_reset(periph); periph_ll_reset(periph);
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
@@ -98,12 +99,12 @@ IRAM_ATTR void wifi_bt_common_module_enable(void)
#if SOC_MODEM_CLOCK_IS_INDEPENDENT #if SOC_MODEM_CLOCK_IS_INDEPENDENT
modem_clock_module_enable(PERIPH_PHY_MODULE); modem_clock_module_enable(PERIPH_PHY_MODULE);
#else #else
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) {
periph_ll_wifi_bt_module_enable_clk(); periph_ll_wifi_bt_module_enable_clk();
} }
ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++; ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++;
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
@@ -112,12 +113,12 @@ IRAM_ATTR void wifi_bt_common_module_disable(void)
#if SOC_MODEM_CLOCK_IS_INDEPENDENT #if SOC_MODEM_CLOCK_IS_INDEPENDENT
modem_clock_module_disable(PERIPH_PHY_MODULE); modem_clock_module_disable(PERIPH_PHY_MODULE);
#else #else
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]--; ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]--;
if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) {
periph_ll_wifi_bt_module_disable_clk(); periph_ll_wifi_bt_module_disable_clk();
} }
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
#endif //#if SOC_BT_SUPPORTED || SOC_WIFI_SUPPORTED #endif //#if SOC_BT_SUPPORTED || SOC_WIFI_SUPPORTED
@@ -129,9 +130,9 @@ void wifi_module_enable(void)
#if SOC_MODEM_CLOCK_IS_INDEPENDENT #if SOC_MODEM_CLOCK_IS_INDEPENDENT
modem_clock_module_enable(PERIPH_WIFI_MODULE); modem_clock_module_enable(PERIPH_WIFI_MODULE);
#else #else
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
periph_ll_wifi_module_enable_clk_clear_rst(); periph_ll_wifi_module_enable_clk_clear_rst();
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
@@ -140,9 +141,9 @@ void wifi_module_disable(void)
#if SOC_MODEM_CLOCK_IS_INDEPENDENT #if SOC_MODEM_CLOCK_IS_INDEPENDENT
modem_clock_module_disable(PERIPH_WIFI_MODULE); modem_clock_module_disable(PERIPH_WIFI_MODULE);
#else #else
portENTER_CRITICAL_SAFE(&periph_spinlock); esp_os_enter_critical_safe(&periph_spinlock);
periph_ll_wifi_module_disable_clk_set_rst(); periph_ll_wifi_module_disable_clk_set_rst();
portEXIT_CRITICAL_SAFE(&periph_spinlock); esp_os_exit_critical_safe(&periph_spinlock);
#endif #endif
} }
#endif // CONFIG_ESP_WIFI_ENABLED #endif // CONFIG_ESP_WIFI_ENABLED

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -18,6 +18,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -34,16 +35,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -56,26 +57,26 @@ static int s_sar_power_on_cnt;
static void s_sar_power_acquire(void) static void s_sar_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@@ -37,16 +38,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
@@ -57,27 +58,27 @@ static int s_pwdet_power_on_cnt;
void sar_periph_ctrl_pwdet_power_acquire(void) void sar_periph_ctrl_pwdet_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_pwdet_power_on_cnt++; s_pwdet_power_on_cnt++;
if (s_pwdet_power_on_cnt == 1) { if (s_pwdet_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_pwdet_power_release(void) void sar_periph_ctrl_pwdet_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_pwdet_power_on_cnt--; s_pwdet_power_on_cnt--;
/* Sanity check */ /* Sanity check */
if (s_pwdet_power_on_cnt < 0) { if (s_pwdet_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_pwdet_power_on_cnt == 0) { } else if (s_pwdet_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
@@ -88,28 +89,28 @@ static int s_sar_power_on_cnt;
static void s_sar_adc_power_acquire(void) static void s_sar_adc_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
regi2c_saradc_enable(); regi2c_saradc_enable();
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON); adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_adc_power_release(void) static void s_sar_adc_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
adc_ll_digi_set_power_manage(ADC_LL_POWER_BY_FSM); adc_ll_digi_set_power_manage(ADC_LL_POWER_BY_FSM);
} }
regi2c_saradc_disable(); regi2c_saradc_disable();
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_adc_oneshot_power_acquire(void) void sar_periph_ctrl_adc_oneshot_power_acquire(void)

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@ Don't put any other code into this file. */
#include "hal/adc_types.h" #include "hal/adc_types.h"
#include "hal/adc_hal_common.h" #include "hal/adc_hal_common.h"
#include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/critical_section.h"
extern portMUX_TYPE rtc_spinlock; extern portMUX_TYPE rtc_spinlock;
@@ -23,9 +24,9 @@ static __attribute__((constructor)) void adc2_init_code_calibration(void)
{ {
adc_hal_calibration_init(ADC_UNIT_2); adc_hal_calibration_init(ADC_UNIT_2);
adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12);
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12);
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
} }
/** Don't call `adc2_cal_include` in user code. */ /** Don't call `adc2_cal_include` in user code. */

View File

@@ -20,6 +20,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@@ -37,16 +38,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
@@ -57,27 +58,27 @@ static int s_pwdet_power_on_cnt;
void sar_periph_ctrl_pwdet_power_acquire(void) void sar_periph_ctrl_pwdet_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_pwdet_power_on_cnt++; s_pwdet_power_on_cnt++;
if (s_pwdet_power_on_cnt == 1) { if (s_pwdet_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_pwdet_power_release(void) void sar_periph_ctrl_pwdet_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_pwdet_power_on_cnt--; s_pwdet_power_on_cnt--;
/* Sanity check */ /* Sanity check */
if (s_pwdet_power_on_cnt < 0) { if (s_pwdet_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_pwdet_power_on_cnt == 0) { } else if (s_pwdet_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
@@ -88,28 +89,28 @@ static int s_sar_power_on_cnt;
static void s_sar_adc_power_acquire(void) static void s_sar_adc_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
regi2c_saradc_enable(); regi2c_saradc_enable();
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON); adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_adc_power_release(void) static void s_sar_adc_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
adc_ll_digi_set_power_manage(ADC_LL_POWER_BY_FSM); adc_ll_digi_set_power_manage(ADC_LL_POWER_BY_FSM);
} }
regi2c_saradc_disable(); regi2c_saradc_disable();
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_adc_oneshot_power_acquire(void) void sar_periph_ctrl_adc_oneshot_power_acquire(void)

View File

@@ -9,12 +9,13 @@
#include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_clk_tree_common.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
#if CONFIG_ULP_COPROC_ENABLED #if CONFIG_ULP_COPROC_ENABLED
@@ -29,13 +30,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -50,7 +51,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -69,13 +70,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -83,5 +84,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -34,16 +35,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(true); sar_ctrl_ll_force_power_ctrl_from_pwdet(true);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(false); sar_ctrl_ll_force_power_ctrl_from_pwdet(false);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -58,26 +59,26 @@ static void s_sar_power_acquire(void)
{ {
modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
regi2c_saradc_enable(); regi2c_saradc_enable();
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
regi2c_saradc_disable(); regi2c_saradc_disable();
modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
} }

View File

@@ -9,12 +9,13 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
#if CONFIG_ULP_COPROC_ENABLED #if CONFIG_ULP_COPROC_ENABLED
@@ -29,13 +30,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -49,7 +50,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -68,13 +69,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -82,5 +83,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -35,16 +36,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(true); sar_ctrl_ll_force_power_ctrl_from_pwdet(true);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(false); sar_ctrl_ll_force_power_ctrl_from_pwdet(false);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -59,26 +60,26 @@ static void s_sar_power_acquire(void)
{ {
modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
regi2c_saradc_enable(); regi2c_saradc_enable();
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
regi2c_saradc_disable(); regi2c_saradc_disable();
modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
} }

View File

@@ -7,12 +7,13 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
#if CONFIG_ULP_COPROC_ENABLED #if CONFIG_ULP_COPROC_ENABLED
@@ -27,13 +28,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -47,7 +48,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -66,13 +67,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -80,5 +81,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -34,16 +35,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(true); sar_ctrl_ll_force_power_ctrl_from_pwdet(true);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(false); sar_ctrl_ll_force_power_ctrl_from_pwdet(false);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -58,26 +59,26 @@ static void s_sar_power_acquire(void)
{ {
modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
regi2c_saradc_enable(); regi2c_saradc_enable();
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
regi2c_saradc_disable(); regi2c_saradc_disable();
modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
} }

View File

@@ -7,12 +7,13 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
static rtc_io_status_t s_rtc_io_status = { static rtc_io_status_t s_rtc_io_status = {
@@ -24,13 +25,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -44,7 +45,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -63,13 +64,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -77,5 +78,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -19,6 +19,7 @@
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -34,16 +35,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(true); sar_ctrl_ll_force_power_ctrl_from_pwdet(true);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_force_power_ctrl_from_pwdet(false); sar_ctrl_ll_force_power_ctrl_from_pwdet(false);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -58,26 +59,26 @@ static void s_sar_power_acquire(void)
{ {
modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
regi2c_saradc_enable(); regi2c_saradc_enable();
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
regi2c_saradc_disable(); regi2c_saradc_disable();
modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE);
} }

View File

@@ -8,12 +8,13 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
static rtc_io_status_t s_rtc_io_status = { static rtc_io_status_t s_rtc_io_status = {
@@ -25,13 +26,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -45,7 +46,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -64,13 +65,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -78,5 +79,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -11,6 +11,7 @@
#include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_clk_tree_common.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
@@ -32,13 +33,13 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
bool clk_conflict = false; bool clk_conflict = false;
// check is the IO MUX has been set to another clock source // check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true; clk_conflict = true;
} else { } else {
s_io_mux_clk_src = clk_src; s_io_mux_clk_src = clk_src;
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) { if (clk_conflict) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@@ -54,7 +55,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error"); assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error");
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -73,13 +74,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error"); assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error");
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -87,5 +88,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/esp_modem_clock.h" #include "esp_private/esp_modem_clock.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
static const char *TAG = "sar_periph_ctrl"; static const char *TAG = "sar_periph_ctrl";
@@ -34,16 +35,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -56,28 +57,28 @@ static int s_sar_power_on_cnt;
static void s_sar_power_acquire(void) static void s_sar_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
regi2c_saradc_enable(); regi2c_saradc_enable();
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
} }
regi2c_saradc_disable(); regi2c_saradc_disable();
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@ Don't put any other code into this file. */
#include "hal/adc_types.h" #include "hal/adc_types.h"
#include "hal/adc_hal_common.h" #include "hal/adc_hal_common.h"
#include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/critical_section.h"
extern portMUX_TYPE rtc_spinlock; extern portMUX_TYPE rtc_spinlock;
@@ -23,9 +24,9 @@ static __attribute__((constructor)) void adc2_init_code_calibration(void)
{ {
adc_hal_calibration_init(ADC_UNIT_2); adc_hal_calibration_init(ADC_UNIT_2);
adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12);
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12);
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
} }
/** Don't call `adc2_cal_include` in user code. */ /** Don't call `adc2_cal_include` in user code. */

View File

@@ -8,12 +8,13 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/critical_section.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \ #define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \ for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \ _rc_cnt ? (esp_os_enter_critical(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--) esp_os_exit_critical(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
@@ -22,7 +23,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
} }
extern portMUX_TYPE rtc_spinlock; extern portMUX_TYPE rtc_spinlock;
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static rtc_io_status_t s_rtc_io_status = { static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 }, .rtc_io_enabled_cnt = { 0 },
@@ -32,7 +33,7 @@ static rtc_io_status_t s_rtc_io_status = {
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -51,13 +52,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -65,5 +66,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@@ -37,16 +38,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
@@ -57,29 +58,29 @@ static int s_sar_power_on_cnt;
void s_sar_power_acquire(void) void s_sar_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
regi2c_saradc_enable(); regi2c_saradc_enable();
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void s_sar_power_release(void) void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
/* Sanity check */ /* Sanity check */
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
} }
regi2c_saradc_disable(); regi2c_saradc_disable();
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------

View File

@@ -8,12 +8,13 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/critical_section.h"
#include "hal/rtc_io_ll.h" #include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \ #define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \ for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \ _rc_cnt ? (esp_os_enter_critical(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--) esp_os_exit_critical(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{ {
@@ -32,7 +33,7 @@ static rtc_io_status_t s_rtc_io_status = {
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
if (enable) { if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
@@ -51,13 +52,13 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
rtcio_ll_enable_io_clock(true); rtcio_ll_enable_io_clock(true);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{ {
assert(gpio_num != GPIO_NUM_NC); assert(gpio_num != GPIO_NUM_NC);
portENTER_CRITICAL(&s_io_mux_spinlock); esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) { if (s_rtc_io_status.rtc_io_using_mask == 0) {
@@ -65,5 +66,5 @@ void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
rtcio_ll_enable_io_clock(false); rtcio_ll_enable_io_clock(false);
} }
} }
portEXIT_CRITICAL(&s_io_mux_spinlock); esp_os_exit_critical(&s_io_mux_spinlock);
} }

View File

@@ -20,6 +20,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_private/sar_periph_ctrl.h" #include "esp_private/sar_periph_ctrl.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/sar_ctrl_ll.h" #include "hal/sar_ctrl_ll.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@@ -37,16 +38,16 @@ void sar_periph_ctrl_init(void)
void sar_periph_ctrl_power_enable(void) void sar_periph_ctrl_power_enable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
void sar_periph_ctrl_power_disable(void) void sar_periph_ctrl_power_disable(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
/** /**
@@ -59,28 +60,28 @@ static int s_sar_power_on_cnt;
static void s_sar_power_acquire(void) static void s_sar_power_acquire(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
regi2c_saradc_enable(); regi2c_saradc_enable();
s_sar_power_on_cnt++; s_sar_power_on_cnt++;
if (s_sar_power_on_cnt == 1) { if (s_sar_power_on_cnt == 1) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
} }
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }
static void s_sar_power_release(void) static void s_sar_power_release(void)
{ {
portENTER_CRITICAL_SAFE(&rtc_spinlock); esp_os_enter_critical_safe(&rtc_spinlock);
s_sar_power_on_cnt--; s_sar_power_on_cnt--;
if (s_sar_power_on_cnt < 0) { if (s_sar_power_on_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
abort(); abort();
} else if (s_sar_power_on_cnt == 0) { } else if (s_sar_power_on_cnt == 0) {
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
} }
regi2c_saradc_disable(); regi2c_saradc_disable();
portEXIT_CRITICAL_SAFE(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);
} }

View File

@@ -13,17 +13,18 @@
#include "hal/regi2c_ctrl_ll.h" #include "hal/regi2c_ctrl_ll.h"
#include "esp_hw_log.h" #include "esp_hw_log.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_private/critical_section.h"
static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) mux = portMUX_INITIALIZER_UNLOCKED;
static DRAM_ATTR __attribute__((unused)) const char *TAG = "REGI2C"; static DRAM_ATTR __attribute__((unused)) const char *TAG = "REGI2C";
uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add) uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add)
{ {
REGI2C_CLOCK_ENABLE(); REGI2C_CLOCK_ENABLE();
portENTER_CRITICAL_SAFE(&mux); esp_os_enter_critical_safe(&mux);
uint8_t value = regi2c_read_reg_raw(block, host_id, reg_add); uint8_t value = regi2c_read_reg_raw(block, host_id, reg_add);
portEXIT_CRITICAL_SAFE(&mux); esp_os_exit_critical_safe(&mux);
REGI2C_CLOCK_DISABLE(); REGI2C_CLOCK_DISABLE();
return value; return value;
} }
@@ -31,9 +32,9 @@ uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add)
uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
{ {
REGI2C_CLOCK_ENABLE(); REGI2C_CLOCK_ENABLE();
portENTER_CRITICAL_SAFE(&mux); esp_os_enter_critical_safe(&mux);
uint8_t value = regi2c_read_reg_mask_raw(block, host_id, reg_add, msb, lsb); uint8_t value = regi2c_read_reg_mask_raw(block, host_id, reg_add, msb, lsb);
portEXIT_CRITICAL_SAFE(&mux); esp_os_exit_critical_safe(&mux);
REGI2C_CLOCK_DISABLE(); REGI2C_CLOCK_DISABLE();
return value; return value;
} }
@@ -41,29 +42,29 @@ uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_ad
void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
{ {
REGI2C_CLOCK_ENABLE(); REGI2C_CLOCK_ENABLE();
portENTER_CRITICAL_SAFE(&mux); esp_os_enter_critical_safe(&mux);
regi2c_write_reg_raw(block, host_id, reg_add, data); regi2c_write_reg_raw(block, host_id, reg_add, data);
portEXIT_CRITICAL_SAFE(&mux); esp_os_exit_critical_safe(&mux);
REGI2C_CLOCK_DISABLE(); REGI2C_CLOCK_DISABLE();
} }
void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
{ {
REGI2C_CLOCK_ENABLE(); REGI2C_CLOCK_ENABLE();
portENTER_CRITICAL_SAFE(&mux); esp_os_enter_critical_safe(&mux);
regi2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data); regi2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data);
portEXIT_CRITICAL_SAFE(&mux); esp_os_exit_critical_safe(&mux);
REGI2C_CLOCK_DISABLE(); REGI2C_CLOCK_DISABLE();
} }
void regi2c_enter_critical(void) void regi2c_enter_critical(void)
{ {
portENTER_CRITICAL_SAFE(&mux); esp_os_enter_critical_safe(&mux);
} }
void regi2c_exit_critical(void) void regi2c_exit_critical(void)
{ {
portEXIT_CRITICAL_SAFE(&mux); esp_os_exit_critical_safe(&mux);
} }
/** /**

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -18,6 +18,7 @@
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#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_attr.h" #include "esp_attr.h"
@@ -60,29 +61,29 @@ typedef struct rtc_isr_handler_ {
static DRAM_ATTR SLIST_HEAD(rtc_isr_handler_list_, rtc_isr_handler_) s_rtc_isr_handler_list = static DRAM_ATTR SLIST_HEAD(rtc_isr_handler_list_, rtc_isr_handler_) s_rtc_isr_handler_list =
SLIST_HEAD_INITIALIZER(s_rtc_isr_handler_list); SLIST_HEAD_INITIALIZER(s_rtc_isr_handler_list);
static DRAM_ATTR portMUX_TYPE s_rtc_isr_handler_list_lock = portMUX_INITIALIZER_UNLOCKED; static DRAM_ATTR portMUX_TYPE __attribute__((unused)) s_rtc_isr_handler_list_lock = portMUX_INITIALIZER_UNLOCKED;
static intr_handle_t s_rtc_isr_handle; static intr_handle_t s_rtc_isr_handle;
IRAM_ATTR static void rtc_isr(void* arg) IRAM_ATTR static void rtc_isr(void* arg)
{ {
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG); uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
rtc_isr_handler_t* it; rtc_isr_handler_t* it;
portENTER_CRITICAL_ISR(&s_rtc_isr_handler_list_lock); esp_os_enter_critical_isr(&s_rtc_isr_handler_list_lock);
SLIST_FOREACH(it, &s_rtc_isr_handler_list, next) { SLIST_FOREACH(it, &s_rtc_isr_handler_list, next) {
if (it->mask & status) { if (it->mask & status) {
portEXIT_CRITICAL_ISR(&s_rtc_isr_handler_list_lock); esp_os_exit_critical_isr(&s_rtc_isr_handler_list_lock);
(*it->handler)(it->handler_arg); (*it->handler)(it->handler_arg);
portENTER_CRITICAL_ISR(&s_rtc_isr_handler_list_lock); esp_os_enter_critical_isr(&s_rtc_isr_handler_list_lock);
} }
} }
portEXIT_CRITICAL_ISR(&s_rtc_isr_handler_list_lock); esp_os_exit_critical_isr(&s_rtc_isr_handler_list_lock);
REG_WRITE(RTC_CNTL_INT_CLR_REG, status); REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
} }
static esp_err_t rtc_isr_ensure_installed(void) static esp_err_t rtc_isr_ensure_installed(void)
{ {
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
portENTER_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_enter_critical(&s_rtc_isr_handler_list_lock);
if (s_rtc_isr_handle) { if (s_rtc_isr_handle) {
goto out; goto out;
} }
@@ -95,7 +96,7 @@ static esp_err_t rtc_isr_ensure_installed(void)
} }
rtc_isr_cpu = esp_intr_get_cpu(s_rtc_isr_handle); rtc_isr_cpu = esp_intr_get_cpu(s_rtc_isr_handle);
out: out:
portEXIT_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_exit_critical(&s_rtc_isr_handler_list_lock);
return err; return err;
} }
#endif // SOC_LP_PERIPH_SHARE_INTERRUPT TODO: IDF-8008 #endif // SOC_LP_PERIPH_SHARE_INTERRUPT TODO: IDF-8008
@@ -119,14 +120,14 @@ esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t r
item->handler_arg = handler_arg; item->handler_arg = handler_arg;
item->mask = rtc_intr_mask; item->mask = rtc_intr_mask;
item->flags = flags; item->flags = flags;
portENTER_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_enter_critical(&s_rtc_isr_handler_list_lock);
if (flags & RTC_INTR_FLAG_IRAM) { if (flags & RTC_INTR_FLAG_IRAM) {
s_rtc_isr_noniram_hook(rtc_intr_mask); s_rtc_isr_noniram_hook(rtc_intr_mask);
} else { } else {
s_rtc_isr_noniram_hook_relieve(rtc_intr_mask); s_rtc_isr_noniram_hook_relieve(rtc_intr_mask);
} }
SLIST_INSERT_HEAD(&s_rtc_isr_handler_list, item, next); SLIST_INSERT_HEAD(&s_rtc_isr_handler_list, item, next);
portEXIT_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_exit_critical(&s_rtc_isr_handler_list_lock);
return ESP_OK; return ESP_OK;
#endif #endif
} }
@@ -140,7 +141,7 @@ esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
rtc_isr_handler_t* it; rtc_isr_handler_t* it;
rtc_isr_handler_t* prev = NULL; rtc_isr_handler_t* prev = NULL;
bool found = false; bool found = false;
portENTER_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_enter_critical(&s_rtc_isr_handler_list_lock);
SLIST_FOREACH(it, &s_rtc_isr_handler_list, next) { SLIST_FOREACH(it, &s_rtc_isr_handler_list, next) {
if (it->handler == handler && it->handler_arg == handler_arg) { if (it->handler == handler && it->handler_arg == handler_arg) {
if (it == SLIST_FIRST(&s_rtc_isr_handler_list)) { if (it == SLIST_FIRST(&s_rtc_isr_handler_list)) {
@@ -157,7 +158,7 @@ esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
} }
prev = it; prev = it;
} }
portEXIT_CRITICAL(&s_rtc_isr_handler_list_lock); esp_os_exit_critical(&s_rtc_isr_handler_list_lock);
return found ? ESP_OK : ESP_ERR_INVALID_STATE; return found ? ESP_OK : ESP_ERR_INVALID_STATE;
#endif #endif
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -16,6 +16,7 @@
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/critical_section.h"
extern __attribute__((unused)) portMUX_TYPE rtc_spinlock; extern __attribute__((unused)) portMUX_TYPE rtc_spinlock;
@@ -47,7 +48,7 @@ static uint8_t s_tsens_idx = 2; // Index for temperature attribute, set 2(middle
void temperature_sensor_power_acquire(void) void temperature_sensor_power_acquire(void)
{ {
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
s_temperature_sensor_power_cnt++; s_temperature_sensor_power_cnt++;
if (s_temperature_sensor_power_cnt == 1) { if (s_temperature_sensor_power_cnt == 1) {
regi2c_saradc_enable(); regi2c_saradc_enable();
@@ -60,16 +61,16 @@ void temperature_sensor_power_acquire(void)
} }
temperature_sensor_ll_enable(true); temperature_sensor_ll_enable(true);
} }
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
} }
void temperature_sensor_power_release(void) void temperature_sensor_power_release(void)
{ {
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
s_temperature_sensor_power_cnt--; s_temperature_sensor_power_cnt--;
/* Sanity check */ /* Sanity check */
if (s_temperature_sensor_power_cnt < 0) { if (s_temperature_sensor_power_cnt < 0) {
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
ESP_LOGE(TAG_TSENS, "%s called, but s_temperature_sensor_power_cnt == 0", __func__); ESP_LOGE(TAG_TSENS, "%s called, but s_temperature_sensor_power_cnt == 0", __func__);
abort(); abort();
} else if (s_temperature_sensor_power_cnt == 0) { } else if (s_temperature_sensor_power_cnt == 0) {
@@ -82,7 +83,7 @@ void temperature_sensor_power_release(void)
#endif #endif
regi2c_saradc_disable(); regi2c_saradc_disable();
} }
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
} }
static SAR_PERIPH_CTRL_COMMON_FN_ATTR int temperature_sensor_get_raw_value(void) static SAR_PERIPH_CTRL_COMMON_FN_ATTR int temperature_sensor_get_raw_value(void)
@@ -98,7 +99,7 @@ void temp_sensor_sync_tsens_idx(int tsens_idx)
int16_t temp_sensor_get_raw_value(bool *range_changed) int16_t temp_sensor_get_raw_value(bool *range_changed)
{ {
portENTER_CRITICAL(&rtc_spinlock); esp_os_enter_critical(&rtc_spinlock);
int degree = temperature_sensor_get_raw_value(); int degree = temperature_sensor_get_raw_value();
uint8_t temperature_dac; uint8_t temperature_dac;
@@ -109,7 +110,7 @@ int16_t temp_sensor_get_raw_value(bool *range_changed)
if (range_changed != NULL) { if (range_changed != NULL) {
*range_changed = false; *range_changed = false;
} }
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
return degree; return degree;
} }
@@ -141,7 +142,7 @@ int16_t temp_sensor_get_raw_value(bool *range_changed)
*range_changed = true; *range_changed = true;
} }
portEXIT_CRITICAL(&rtc_spinlock); esp_os_exit_critical(&rtc_spinlock);
return degree; return degree;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -10,7 +10,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_private/sleep_event.h" #include "esp_private/sleep_event.h"
#include "esp_private/critical_section.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_check.h" #include "esp_check.h"
@@ -31,12 +31,12 @@ esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id,
return ESP_ERR_NO_MEM; /* Memory allocation failed */ return ESP_ERR_NO_MEM; /* Memory allocation failed */
} }
portENTER_CRITICAL(&s_sleep_event_mutex); esp_os_enter_critical(&s_sleep_event_mutex);
esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]); esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]);
while (*current_ptr != NULL) { while (*current_ptr != NULL) {
if (((*current_ptr)->cb) == (event_cb_conf->cb)) { if (((*current_ptr)->cb) == (event_cb_conf->cb)) {
free(new_config); free(new_config);
portEXIT_CRITICAL(&s_sleep_event_mutex); esp_os_exit_critical(&s_sleep_event_mutex);
return ESP_FAIL; return ESP_FAIL;
} }
current_ptr = &((*current_ptr)->next); current_ptr = &((*current_ptr)->next);
@@ -48,7 +48,7 @@ esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id,
} }
new_config->next = *current_ptr; new_config->next = *current_ptr;
*current_ptr = new_config; *current_ptr = new_config;
portEXIT_CRITICAL(&s_sleep_event_mutex); esp_os_exit_critical(&s_sleep_event_mutex);
return ESP_OK; return ESP_OK;
} }
@@ -56,7 +56,7 @@ esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_i
if (cb == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) { if (cb == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL(&s_sleep_event_mutex); esp_os_enter_critical(&s_sleep_event_mutex);
esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]); esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]);
while (*current_ptr != NULL) { while (*current_ptr != NULL) {
if (((*current_ptr)->cb) == cb) { if (((*current_ptr)->cb) == cb) {
@@ -67,7 +67,7 @@ esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_i
} }
current_ptr = &((*current_ptr)->next); current_ptr = &((*current_ptr)->next);
} }
portEXIT_CRITICAL(&s_sleep_event_mutex); esp_os_exit_critical(&s_sleep_event_mutex);
return ESP_OK; return ESP_OK;
} }
#endif #endif

View File

@@ -23,6 +23,7 @@
#include "esp_private/sleep_event.h" #include "esp_private/sleep_event.h"
#include "esp_private/system_internal.h" #include "esp_private/system_internal.h"
#include "esp_private/io_mux.h" #include "esp_private/io_mux.h"
#include "esp_private/critical_section.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_newlib.h" #include "esp_newlib.h"
#include "esp_timer.h" #include "esp_timer.h"
@@ -318,7 +319,7 @@ static bool s_light_sleep_wakeup = false;
/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
is not thread-safe, so we need to disable interrupts before going to deep sleep. */ is not thread-safe, so we need to disable interrupts before going to deep sleep. */
static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED;
static const char *TAG = "sleep"; static const char *TAG = "sleep";
static RTC_FAST_ATTR int32_t s_sleep_sub_mode_ref_cnt[ESP_SLEEP_MODE_MAX] = { 0 }; static RTC_FAST_ATTR int32_t s_sleep_sub_mode_ref_cnt[ESP_SLEEP_MODE_MAX] = { 0 };
@@ -326,9 +327,9 @@ static RTC_FAST_ATTR int32_t s_sleep_sub_mode_ref_cnt[ESP_SLEEP_MODE_MAX] = { 0
void esp_sleep_overhead_out_time_refresh(void) void esp_sleep_overhead_out_time_refresh(void)
{ {
portENTER_CRITICAL(&s_config.lock); esp_os_enter_critical(&s_config.lock);
s_config.overhead_out_need_remeasure = true; s_config.overhead_out_need_remeasure = true;
portEXIT_CRITICAL(&s_config.lock); esp_os_exit_critical(&s_config.lock);
} }
static uint32_t get_power_down_flags(void); static uint32_t get_power_down_flags(void);
@@ -474,28 +475,28 @@ esp_err_t esp_deep_sleep_try(uint64_t time_in_us)
static esp_err_t s_sleep_hook_register(esp_deep_sleep_cb_t new_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS]) static esp_err_t s_sleep_hook_register(esp_deep_sleep_cb_t new_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS])
{ {
portENTER_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_enter_critical(&spinlock_rtc_deep_sleep);
for (int n = 0; n < MAX_DSLP_HOOKS; n++) { for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
if (s_cb_array[n]==NULL || s_cb_array[n]==new_cb) { if (s_cb_array[n]==NULL || s_cb_array[n]==new_cb) {
s_cb_array[n]=new_cb; s_cb_array[n]=new_cb;
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_exit_critical(&spinlock_rtc_deep_sleep);
return ESP_OK; return ESP_OK;
} }
} }
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_exit_critical(&spinlock_rtc_deep_sleep);
ESP_LOGE(TAG, "Registered deepsleep callbacks exceeds MAX_DSLP_HOOKS"); ESP_LOGE(TAG, "Registered deepsleep callbacks exceeds MAX_DSLP_HOOKS");
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
static void s_sleep_hook_deregister(esp_deep_sleep_cb_t old_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS]) static void s_sleep_hook_deregister(esp_deep_sleep_cb_t old_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS])
{ {
portENTER_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_enter_critical(&spinlock_rtc_deep_sleep);
for (int n = 0; n < MAX_DSLP_HOOKS; n++) { for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
if(s_cb_array[n] == old_cb) { if(s_cb_array[n] == old_cb) {
s_cb_array[n] = NULL; s_cb_array[n] = NULL;
} }
} }
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_exit_critical(&spinlock_rtc_deep_sleep);
} }
esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb) esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)
@@ -1223,7 +1224,7 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
/* Disable interrupts and stall another core in case another task writes /* Disable interrupts and stall another core in case another task writes
* to RTC memory while we calculate RTC memory CRC. * to RTC memory while we calculate RTC memory CRC.
*/ */
portENTER_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_enter_critical(&spinlock_rtc_deep_sleep);
esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_other_cpu();
esp_ipc_isr_stall_pause(); esp_ipc_isr_stall_pause();
@@ -1294,7 +1295,7 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
// Never returns here, except that the sleep is rejected. // Never returns here, except that the sleep is rejected.
esp_ipc_isr_stall_resume(); esp_ipc_isr_stall_resume();
esp_ipc_isr_release_other_cpu(); esp_ipc_isr_release_other_cpu();
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); esp_os_exit_critical(&spinlock_rtc_deep_sleep);
return err; return err;
} }
@@ -1392,7 +1393,7 @@ esp_err_t esp_light_sleep_start(void)
timerret = esp_task_wdt_stop(); timerret = esp_task_wdt_stop();
#endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER
portENTER_CRITICAL(&s_config.lock); esp_os_enter_critical(&s_config.lock);
/* /*
Note: We are about to stall the other CPU via the esp_ipc_isr_stall_other_cpu(). However, there is a chance of Note: We are about to stall the other CPU via the esp_ipc_isr_stall_other_cpu(). However, there is a chance of
deadlock if after stalling the other CPU, we attempt to take spinlocks already held by the other CPU that is. deadlock if after stalling the other CPU, we attempt to take spinlocks already held by the other CPU that is.
@@ -1643,7 +1644,7 @@ esp_err_t esp_light_sleep_start(void)
s_config.overhead_out_need_remeasure = false; s_config.overhead_out_need_remeasure = false;
} }
portEXIT_CRITICAL(&s_config.lock); esp_os_exit_critical(&s_config.lock);
return err; return err;
} }
@@ -1745,10 +1746,10 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
#endif #endif
portENTER_CRITICAL(&s_config.lock); esp_os_enter_critical(&s_config.lock);
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN; s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us; s_config.sleep_duration = time_in_us;
portEXIT_CRITICAL(&s_config.lock); esp_os_exit_critical(&s_config.lock);
return ESP_OK; return ESP_OK;
} }
@@ -2335,7 +2336,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&s_config.lock); esp_os_enter_critical_safe(&s_config.lock);
int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \ int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \
: (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \ : (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \
@@ -2343,7 +2344,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
if (refs == 0) { if (refs == 0) {
s_config.domain[domain].pd_option = option; s_config.domain[domain].pd_option = option;
} }
portEXIT_CRITICAL_SAFE(&s_config.lock); esp_os_exit_critical_safe(&s_config.lock);
assert(refs >= 0); assert(refs >= 0);
return ESP_OK; return ESP_OK;
} }
@@ -2354,14 +2355,14 @@ esp_err_t esp_sleep_sub_mode_config(esp_sleep_sub_mode_t mode, bool activate)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&s_config.lock); esp_os_enter_critical_safe(&s_config.lock);
if (activate) { if (activate) {
s_sleep_sub_mode_ref_cnt[mode]++; s_sleep_sub_mode_ref_cnt[mode]++;
} else { } else {
s_sleep_sub_mode_ref_cnt[mode]--; s_sleep_sub_mode_ref_cnt[mode]--;
} }
assert(s_sleep_sub_mode_ref_cnt[mode] >= 0); assert(s_sleep_sub_mode_ref_cnt[mode] >= 0);
portEXIT_CRITICAL_SAFE(&s_config.lock); esp_os_exit_critical_safe(&s_config.lock);
return ESP_OK; return ESP_OK;
} }
@@ -2371,9 +2372,9 @@ esp_err_t esp_sleep_sub_mode_force_disable(esp_sleep_sub_mode_t mode)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
portENTER_CRITICAL_SAFE(&s_config.lock); esp_os_enter_critical_safe(&s_config.lock);
s_sleep_sub_mode_ref_cnt[mode] = 0; s_sleep_sub_mode_ref_cnt[mode] = 0;
portEXIT_CRITICAL_SAFE(&s_config.lock); esp_os_exit_critical_safe(&s_config.lock);
return ESP_OK; return ESP_OK;
} }
@@ -2406,11 +2407,11 @@ esp_err_t esp_sleep_clock_config(esp_sleep_clock_t clock, esp_sleep_clock_option
} }
int __attribute__((unused)) refs; int __attribute__((unused)) refs;
portENTER_CRITICAL_SAFE(&s_config.lock); esp_os_enter_critical_safe(&s_config.lock);
refs = (option == ESP_SLEEP_CLOCK_OPTION_UNGATE) ? s_config.clock_icg_refs[clock]++ \ refs = (option == ESP_SLEEP_CLOCK_OPTION_UNGATE) ? s_config.clock_icg_refs[clock]++ \
: (option == ESP_SLEEP_CLOCK_OPTION_GATE) ? --s_config.clock_icg_refs[clock] \ : (option == ESP_SLEEP_CLOCK_OPTION_GATE) ? --s_config.clock_icg_refs[clock] \
: s_config.clock_icg_refs[clock]; : s_config.clock_icg_refs[clock];
portEXIT_CRITICAL_SAFE(&s_config.lock); esp_os_exit_critical_safe(&s_config.lock);
assert(refs >= 0); assert(refs >= 0);
return ESP_OK; return ESP_OK;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -9,6 +9,7 @@
#include <stdatomic.h> #include <stdatomic.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_private/spi_share_hw_ctrl.h" #include "esp_private/spi_share_hw_ctrl.h"
#include "esp_private/critical_section.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "stdatomic.h" #include "stdatomic.h"
@@ -368,9 +369,9 @@ SPI_BUS_LOCK_ISR_ATTR static inline bool acquire_core(spi_bus_lock_dev_t *dev_ha
spi_bus_lock_t* lock = dev_handle->parent; spi_bus_lock_t* lock = dev_handle->parent;
//For this critical section, search `@note 1` in this file, to know details //For this critical section, search `@note 1` in this file, to know details
portENTER_CRITICAL_SAFE(&s_spinlock); esp_os_enter_critical_safe(&s_spinlock);
uint32_t status = lock_status_fetch_set(lock, dev_handle->mask & LOCK_MASK); uint32_t status = lock_status_fetch_set(lock, dev_handle->mask & LOCK_MASK);
portEXIT_CRITICAL_SAFE(&s_spinlock); esp_os_exit_critical_safe(&s_spinlock);
// Check all bits except WEAK_BG // Check all bits except WEAK_BG
if ((status & (BG_MASK | LOCK_MASK)) == 0) { if ((status & (BG_MASK | LOCK_MASK)) == 0) {
@@ -451,10 +452,10 @@ IRAM_ATTR static inline void acquire_end_core(spi_bus_lock_dev_t *dev_handle)
spi_bus_lock_dev_t* desired_dev = NULL; spi_bus_lock_dev_t* desired_dev = NULL;
//For this critical section, search `@note 1` in this file, to know details //For this critical section, search `@note 1` in this file, to know details
portENTER_CRITICAL_SAFE(&s_spinlock); esp_os_enter_critical_safe(&s_spinlock);
uint32_t status = lock_status_clear(lock, dev_handle->mask & LOCK_MASK); uint32_t status = lock_status_clear(lock, dev_handle->mask & LOCK_MASK);
bool invoke_bg = !schedule_core(lock, status, &desired_dev); bool invoke_bg = !schedule_core(lock, status, &desired_dev);
portEXIT_CRITICAL_SAFE(&s_spinlock); esp_os_exit_critical_safe(&s_spinlock);
if (invoke_bg) { if (invoke_bg) {
bg_enable(lock); bg_enable(lock);