Merge branch 'refactor/dac_common_lock_and_log' into 'master'

refactor(dac): split spinlock, update logging and memory management

See merge request espressif/esp-idf!51826
This commit is contained in:
morris
2026-08-18 22:11:22 +08:00
8 changed files with 96 additions and 105 deletions
+1
View File
@@ -27,6 +27,7 @@ endif()
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "./include" INCLUDE_DIRS "./include"
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES ${priv_req} PRIV_REQUIRES ${priv_req}
REQUIRES esp_hal_ana_conv REQUIRES esp_hal_ana_conv
LDFRAGMENTS "linker.lf" LDFRAGMENTS "linker.lf"
+24 -8
View File
@@ -6,14 +6,24 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "stdatomic.h" #include <stdatomic.h>
#include "dac_priv_common.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "hal/dac_periph.h" #include "hal/dac_periph.h"
#include "hal/dac_types.h" #include "hal/dac_types.h"
#include "hal/dac_ll.h" #include "hal/dac_ll.h"
#include "esp_private/gpio.h" #include "esp_private/gpio.h"
#include "esp_check.h" #include "esp_check.h"
#include "dac_priv_common.h" #include "esp_log.h"
#if ! (SOC_IS(ESP32) || SOC_IS(ESP32S2))
portMUX_TYPE dac_priv_spinlock = portMUX_INITIALIZER_UNLOCKED;
#endif // ! (SOC_IS(ESP32) || SOC_IS(ESP32S2))
/*---------------------------------------------------------------
Channel (analog pad) management
---------------------------------------------------------------*/
typedef enum { typedef enum {
DAC_CHAN_FSM_IDLE, DAC_CHAN_FSM_IDLE,
@@ -26,8 +36,6 @@ static _Atomic dac_channel_fsm_t s_dac_chan_fsm[SOC_DAC_CHAN_NUM] = {
[0 ... SOC_DAC_CHAN_NUM - 1] = DAC_CHAN_FSM_IDLE, [0 ... SOC_DAC_CHAN_NUM - 1] = DAC_CHAN_FSM_IDLE,
}; };
static const char *TAG = "dac_common";
esp_err_t dac_priv_register_channel(dac_channel_t chan_id) esp_err_t dac_priv_register_channel(dac_channel_t chan_id)
{ {
ESP_RETURN_ON_FALSE(IS_VALID_DAC_CHANNEL(chan_id), ESP_ERR_INVALID_ARG, TAG, "channel id is invalid"); ESP_RETURN_ON_FALSE(IS_VALID_DAC_CHANNEL(chan_id), ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
@@ -62,10 +70,10 @@ esp_err_t dac_priv_enable_channel(dac_channel_t chan_id)
if (atomic_compare_exchange_strong(&s_dac_chan_fsm[chan_id], &expected_fsm, DAC_CHAN_FSM_WAIT)) { if (atomic_compare_exchange_strong(&s_dac_chan_fsm[chan_id], &expected_fsm, DAC_CHAN_FSM_WAIT)) {
gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id]; gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id];
gpio_config_as_analog(gpio_num); gpio_config_as_analog(gpio_num);
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_power_on(chan_id); dac_ll_power_on(chan_id);
dac_ll_rtc_sync_by_adc(false); dac_ll_rtc_sync_by_adc(false);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
atomic_store(&s_dac_chan_fsm[chan_id], DAC_CHAN_FSM_ENABLED); atomic_store(&s_dac_chan_fsm[chan_id], DAC_CHAN_FSM_ENABLED);
return ESP_OK; return ESP_OK;
} else { } else {
@@ -80,9 +88,9 @@ esp_err_t dac_priv_disable_channel(dac_channel_t chan_id)
dac_channel_fsm_t expected_fsm = DAC_CHAN_FSM_ENABLED; dac_channel_fsm_t expected_fsm = DAC_CHAN_FSM_ENABLED;
if (atomic_compare_exchange_strong(&s_dac_chan_fsm[chan_id], &expected_fsm, DAC_CHAN_FSM_WAIT)) { if (atomic_compare_exchange_strong(&s_dac_chan_fsm[chan_id], &expected_fsm, DAC_CHAN_FSM_WAIT)) {
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_power_down(chan_id); dac_ll_power_down(chan_id);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
atomic_store(&s_dac_chan_fsm[chan_id], DAC_CHAN_FSM_REGISTERED); atomic_store(&s_dac_chan_fsm[chan_id], DAC_CHAN_FSM_REGISTERED);
return ESP_OK; return ESP_OK;
} else { } else {
@@ -90,3 +98,11 @@ esp_err_t dac_priv_disable_channel(dac_channel_t chan_id)
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} }
} }
#if CONFIG_DAC_ENABLE_DEBUG_LOG
__attribute__((constructor))
static void dac_override_default_log_level(void)
{
esp_log_level_set(TAG, ESP_LOG_DEBUG);
}
#endif
+12 -28
View File
@@ -4,27 +4,22 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#if CONFIG_DAC_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include <assert.h> #include <assert.h>
#include <stdatomic.h> #include <stdatomic.h>
#include <string.h> #include <string.h>
#include "dac_priv_common.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/idf_additions.h" #include "freertos/idf_additions.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/dac_ll.h"
#include "driver/dac_continuous.h" #include "driver/dac_continuous.h"
#include "esp_private/gdma_link.h" #include "esp_private/gdma_link.h"
#include "esp_check.h" #include "esp_check.h"
#include "esp_log.h"
#include "dac_priv_common.h"
#include "dac_priv_dma.h" #include "dac_priv_dma.h"
#if CONFIG_PM_ENABLE #if CONFIG_PM_ENABLE
@@ -33,12 +28,6 @@
#define DAC_DMA_MAX_BUF_SIZE 4092 // Max DMA buffer size is 4095 but better to align with 4 bytes, so set 4092 here #define DAC_DMA_MAX_BUF_SIZE 4092 // Max DMA buffer size is 4095 but better to align with 4 bytes, so set 4092 here
#if CONFIG_DAC_ISR_IRAM_SAFE || CONFIG_DAC_CTRL_FUNC_IN_IRAM
#define DAC_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
#define DAC_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif
#if CONFIG_DAC_ISR_IRAM_SAFE #if CONFIG_DAC_ISR_IRAM_SAFE
#define DAC_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) #define DAC_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED)
#else #else
@@ -84,8 +73,6 @@ typedef enum {
static _Atomic dac_continuous_fsm_t s_dac_cont_fsm = DAC_CONT_FSM_IDLE; static _Atomic dac_continuous_fsm_t s_dac_cont_fsm = DAC_CONT_FSM_IDLE;
static const char *TAG = "dac_continuous";
static esp_err_t s_dac_continuous_stop_sync(dac_continuous_handle_t handle); static esp_err_t s_dac_continuous_stop_sync(dac_continuous_handle_t handle);
static void s_dac_free_dma_desc(dac_continuous_handle_t handle) static void s_dac_free_dma_desc(dac_continuous_handle_t handle)
@@ -212,9 +199,6 @@ static void IRAM_ATTR s_dac_default_intr_handler(void *arg)
esp_err_t dac_continuous_new_channels(const dac_continuous_config_t *cont_cfg, dac_continuous_handle_t *ret_handle) esp_err_t dac_continuous_new_channels(const dac_continuous_config_t *cont_cfg, dac_continuous_handle_t *ret_handle)
{ {
#if CONFIG_DAC_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
/* Parameters validation */ /* Parameters validation */
DAC_NULL_POINTER_CHECK(cont_cfg); DAC_NULL_POINTER_CHECK(cont_cfg);
DAC_NULL_POINTER_CHECK(ret_handle); DAC_NULL_POINTER_CHECK(ret_handle);
@@ -276,9 +260,9 @@ esp_err_t dac_continuous_new_channels(const dac_continuous_config_t *cont_cfg, d
err1, TAG, "Failed to register DAC DMA interrupt"); err1, TAG, "Failed to register DAC DMA interrupt");
/* Connect DAC module to the DMA peripheral */ /* Connect DAC module to the DMA peripheral */
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(true); dac_ll_digi_enable_dma(true);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
/* FSM: WAIT -> REGISTERED */ /* FSM: WAIT -> REGISTERED */
atomic_store(&s_dac_cont_fsm, DAC_CONT_FSM_REGISTERED); atomic_store(&s_dac_cont_fsm, DAC_CONT_FSM_REGISTERED);
@@ -334,9 +318,9 @@ esp_err_t dac_continuous_del_channels(dac_continuous_handle_t handle)
ESP_RETURN_ON_ERROR(dac_dma_periph_deinit(), TAG, "Failed to deinitialize DAC DMA peripheral"); ESP_RETURN_ON_ERROR(dac_dma_periph_deinit(), TAG, "Failed to deinitialize DAC DMA peripheral");
/* Disconnect DAC module from the DMA peripheral */ /* Disconnect DAC module from the DMA peripheral */
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(false); dac_ll_digi_enable_dma(false);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
/* Free allocated resources */ /* Free allocated resources */
s_dac_free_dma_desc(handle); s_dac_free_dma_desc(handle);
@@ -416,9 +400,9 @@ esp_err_t dac_continuous_enable(dac_continuous_handle_t handle)
dac_dma_periph_enable(); dac_dma_periph_enable();
esp_intr_enable(handle->intr_handle); esp_intr_enable(handle->intr_handle);
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(true); dac_ll_digi_enable_dma(true);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
/* FSM: WAIT -> ENABLED */ /* FSM: WAIT -> ENABLED */
atomic_store(&s_dac_cont_fsm, DAC_CONT_FSM_ENABLED); atomic_store(&s_dac_cont_fsm, DAC_CONT_FSM_ENABLED);
@@ -448,9 +432,9 @@ esp_err_t dac_continuous_disable(dac_continuous_handle_t handle)
dac_dma_periph_disable(); dac_dma_periph_disable();
esp_intr_disable(handle->intr_handle); esp_intr_disable(handle->intr_handle);
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(false); dac_ll_digi_enable_dma(false);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
DAC_CHANNEL_MASK_FOREACH(chan, handle->cfg.chan_mask) { DAC_CHANNEL_MASK_FOREACH(chan, handle->cfg.chan_mask) {
dac_priv_disable_channel(chan); dac_priv_disable_channel(chan);
+10 -22
View File
@@ -5,28 +5,19 @@
*/ */
#include <string.h> #include <string.h>
#include "dac_priv_common.h"
#include "driver/dac_cosine.h" #include "driver/dac_cosine.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "dac_priv_common.h" #include "hal/dac_ll.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#if CONFIG_DAC_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_check.h" #include "esp_check.h"
#if CONFIG_PM_ENABLE #include "esp_log.h"
#include "esp_pm.h"
#endif
struct dac_cosine_s { struct dac_cosine_s {
dac_cosine_config_t cfg; /*!< Cosine mode configurations */ dac_cosine_config_t cfg; /*!< Cosine mode configurations */
bool is_started; /*!< Flag: is the channel started(not cosine wave generator) */ bool is_started; /*!< Flag: is the channel started(not cosine wave generator) */
}; };
static const char *TAG = "dac_cosine";
/* Cosine wave generator reference count /* Cosine wave generator reference count
* The cosine wave generator is shared by dac channels */ * The cosine wave generator is shared by dac channels */
static uint32_t s_cwg_refer_cnt = 0; static uint32_t s_cwg_refer_cnt = 0;
@@ -36,9 +27,6 @@ static uint32_t s_cwg_freq = 0;
esp_err_t dac_cosine_new_channel(const dac_cosine_config_t *cos_cfg, dac_cosine_handle_t *ret_handle) esp_err_t dac_cosine_new_channel(const dac_cosine_config_t *cos_cfg, dac_cosine_handle_t *ret_handle)
{ {
#if CONFIG_DAC_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
/* Parameters validation */ /* Parameters validation */
DAC_NULL_POINTER_CHECK(cos_cfg); DAC_NULL_POINTER_CHECK(cos_cfg);
DAC_NULL_POINTER_CHECK(ret_handle); DAC_NULL_POINTER_CHECK(ret_handle);
@@ -49,7 +37,7 @@ esp_err_t dac_cosine_new_channel(const dac_cosine_config_t *cos_cfg, dac_cosine_
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
/* Allocate cosine handle */ /* Allocate cosine handle */
dac_cosine_handle_t handle = heap_caps_calloc(1, sizeof(struct dac_cosine_s), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); dac_cosine_handle_t handle = heap_caps_calloc(1, sizeof(struct dac_cosine_s), DAC_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(handle, ESP_ERR_NO_MEM, TAG, "no memory for the dac cosine handle"); ESP_RETURN_ON_FALSE(handle, ESP_ERR_NO_MEM, TAG, "no memory for the dac cosine handle");
/* Assign configurations */ /* Assign configurations */
handle->cfg = *cos_cfg; handle->cfg = *cos_cfg;
@@ -64,7 +52,7 @@ esp_err_t dac_cosine_new_channel(const dac_cosine_config_t *cos_cfg, dac_cosine_
ESP_LOGW(TAG, "RTC clock calibration failed, using the approximate value as default"); ESP_LOGW(TAG, "RTC clock calibration failed, using the approximate value as default");
rtc_clk_freq = SOC_CLK_RC_FAST_FREQ_APPROX; rtc_clk_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
} }
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
/* Set coefficients for cosine wave generator */ /* Set coefficients for cosine wave generator */
if ((!s_cwg_freq) || cos_cfg->flags.force_set_freq) { if ((!s_cwg_freq) || cos_cfg->flags.force_set_freq) {
dac_ll_cw_set_freq(cos_cfg->freq_hz, rtc_clk_freq); dac_ll_cw_set_freq(cos_cfg->freq_hz, rtc_clk_freq);
@@ -73,7 +61,7 @@ esp_err_t dac_cosine_new_channel(const dac_cosine_config_t *cos_cfg, dac_cosine_
dac_ll_cw_set_atten(cos_cfg->chan_id, cos_cfg->atten); dac_ll_cw_set_atten(cos_cfg->chan_id, cos_cfg->atten);
dac_ll_cw_set_phase(cos_cfg->chan_id, cos_cfg->phase); dac_ll_cw_set_phase(cos_cfg->chan_id, cos_cfg->phase);
dac_ll_cw_set_dc_offset(cos_cfg->chan_id, cos_cfg->offset); dac_ll_cw_set_dc_offset(cos_cfg->chan_id, cos_cfg->offset);
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
*ret_handle = handle; *ret_handle = handle;
return ret; return ret;
@@ -112,7 +100,7 @@ esp_err_t dac_cosine_start(dac_cosine_handle_t handle)
ESP_GOTO_ON_ERROR(dac_priv_enable_channel(handle->cfg.chan_id), err, TAG, ESP_GOTO_ON_ERROR(dac_priv_enable_channel(handle->cfg.chan_id), err, TAG,
"enable dac channel %d failed", handle->cfg.chan_id); "enable dac channel %d failed", handle->cfg.chan_id);
/* Enabled the cosine wave generator if no channel using it before */ /* Enabled the cosine wave generator if no channel using it before */
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
if (s_cwg_refer_cnt == 0) { if (s_cwg_refer_cnt == 0) {
dac_ll_cw_generator_enable(); dac_ll_cw_generator_enable();
} }
@@ -120,7 +108,7 @@ esp_err_t dac_cosine_start(dac_cosine_handle_t handle)
dac_ll_cw_enable_channel(handle->cfg.chan_id, true); dac_ll_cw_enable_channel(handle->cfg.chan_id, true);
s_cwg_refer_cnt++; s_cwg_refer_cnt++;
handle->is_started = true; handle->is_started = true;
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
return ESP_OK; return ESP_OK;
@@ -138,7 +126,7 @@ esp_err_t dac_cosine_stop(dac_cosine_handle_t handle)
/* Enabled DAC channel */ /* Enabled DAC channel */
ESP_RETURN_ON_ERROR(dac_priv_disable_channel(handle->cfg.chan_id), TAG, ESP_RETURN_ON_ERROR(dac_priv_disable_channel(handle->cfg.chan_id), TAG,
"disable dac channel %d failed", handle->cfg.chan_id); "disable dac channel %d failed", handle->cfg.chan_id);
DAC_RTC_ENTER_CRITICAL(); DAC_ENTER_CRITICAL();
/* Disconnect the DAC channel from the cosine wave generator */ /* Disconnect the DAC channel from the cosine wave generator */
dac_ll_cw_enable_channel(handle->cfg.chan_id, false); dac_ll_cw_enable_channel(handle->cfg.chan_id, false);
s_cwg_refer_cnt--; s_cwg_refer_cnt--;
@@ -147,7 +135,7 @@ esp_err_t dac_cosine_stop(dac_cosine_handle_t handle)
dac_ll_cw_generator_disable(); dac_ll_cw_generator_disable();
} }
handle->is_started = false; handle->is_started = false;
DAC_RTC_EXIT_CRITICAL(); DAC_EXIT_CRITICAL();
/* Release the RTC clock */ /* Release the RTC clock */
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(SOC_MOD_CLK_RC_FAST, false), TAG, "RC_FAST clock disable failed"); ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(SOC_MOD_CLK_RC_FAST, false), TAG, "RC_FAST clock disable failed");
+5 -17
View File
@@ -7,28 +7,16 @@
#include <string.h> #include <string.h>
#include "dac_priv_common.h" #include "dac_priv_common.h"
#include "driver/dac_oneshot.h" #include "driver/dac_oneshot.h"
#include "hal/dac_ll.h"
#if CONFIG_DAC_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_check.h" #include "esp_check.h"
#if CONFIG_PM_ENABLE #include "esp_log.h"
#include "esp_pm.h"
#endif
struct dac_oneshot_s { struct dac_oneshot_s {
dac_oneshot_config_t cfg; /*!< Oneshot mode configurations */ dac_oneshot_config_t cfg; /*!< Oneshot mode configurations */
}; };
static const char *TAG = "dac_oneshot";
esp_err_t dac_oneshot_new_channel(const dac_oneshot_config_t *oneshot_cfg, dac_oneshot_handle_t *ret_handle) esp_err_t dac_oneshot_new_channel(const dac_oneshot_config_t *oneshot_cfg, dac_oneshot_handle_t *ret_handle)
{ {
#if CONFIG_DAC_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
/* Parameters validation */ /* Parameters validation */
DAC_NULL_POINTER_CHECK(oneshot_cfg); DAC_NULL_POINTER_CHECK(oneshot_cfg);
DAC_NULL_POINTER_CHECK(ret_handle); DAC_NULL_POINTER_CHECK(ret_handle);
@@ -36,7 +24,7 @@ esp_err_t dac_oneshot_new_channel(const dac_oneshot_config_t *oneshot_cfg, dac_o
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
/* Resources allocation */ /* Resources allocation */
dac_oneshot_handle_t handle = heap_caps_calloc(1, sizeof(struct dac_oneshot_s), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); dac_oneshot_handle_t handle = heap_caps_calloc(1, sizeof(struct dac_oneshot_s), DAC_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(handle, ESP_ERR_NO_MEM, TAG, "no memory for the dac oneshot handle"); ESP_RETURN_ON_FALSE(handle, ESP_ERR_NO_MEM, TAG, "no memory for the dac oneshot handle");
handle->cfg = *oneshot_cfg; handle->cfg = *oneshot_cfg;
@@ -75,9 +63,9 @@ esp_err_t dac_oneshot_output_voltage(dac_oneshot_handle_t handle, uint8_t digi_v
} }
/* Set the voltage by the digital value */ /* Set the voltage by the digital value */
DAC_RTC_ENTER_CRITICAL_SAFE(); DAC_ENTER_CRITICAL_SAFE();
dac_ll_update_output_value(handle->cfg.chan_id, digi_value); dac_ll_update_output_value(handle->cfg.chan_id, digi_value);
DAC_RTC_EXIT_CRITICAL_SAFE(); DAC_EXIT_CRITICAL_SAFE();
return ESP_OK; return ESP_OK;
} }
+36 -6
View File
@@ -6,26 +6,56 @@
#pragma once #pragma once
#include "sdkconfig.h"
#if CONFIG_DAC_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for DAC driver
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "hal/dac_types.h" #include "hal/dac_types.h"
#include "hal/dac_ll.h" #include "esp_log.h"
#include "esp_check.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_heap_caps.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern portMUX_TYPE rtc_spinlock; /*!< Extern global rtc spinlock */ ESP_LOG_ATTR_TAG(TAG, "dac");
#define DAC_RTC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) /**
#define DAC_RTC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) * DAC driver spinlock
*
* - ESP32 / ESP32-S2: use the global rtc_spinlock
* - ESP32-S31: dedicated DAC register block, use dac_priv_spinlock
*/
#if SOC_IS(ESP32) || SOC_IS(ESP32S2)
extern portMUX_TYPE rtc_spinlock;
#define DAC_RTC_ENTER_CRITICAL_SAFE() portENTER_CRITICAL_SAFE(&rtc_spinlock) #define DAC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define DAC_RTC_EXIT_CRITICAL_SAFE() portEXIT_CRITICAL_SAFE(&rtc_spinlock) #define DAC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
#define DAC_ENTER_CRITICAL_SAFE() portENTER_CRITICAL_SAFE(&rtc_spinlock)
#define DAC_EXIT_CRITICAL_SAFE() portEXIT_CRITICAL_SAFE(&rtc_spinlock)
#else
extern portMUX_TYPE dac_priv_spinlock;
#define DAC_ENTER_CRITICAL() portENTER_CRITICAL(&dac_priv_spinlock)
#define DAC_EXIT_CRITICAL() portEXIT_CRITICAL(&dac_priv_spinlock)
#define DAC_ENTER_CRITICAL_SAFE() portENTER_CRITICAL_SAFE(&dac_priv_spinlock)
#define DAC_EXIT_CRITICAL_SAFE() portEXIT_CRITICAL_SAFE(&dac_priv_spinlock)
#endif // SOC_IS(ESP32) || SOC_IS(ESP32S2)
#define DAC_NULL_POINTER_CHECK(p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL") #define DAC_NULL_POINTER_CHECK(p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL")
#define DAC_NULL_POINTER_CHECK_ISR(p) ESP_RETURN_ON_FALSE_ISR((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL") #define DAC_NULL_POINTER_CHECK_ISR(p) ESP_RETURN_ON_FALSE_ISR((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL")
#if CONFIG_DAC_ISR_IRAM_SAFE || CONFIG_DAC_CTRL_FUNC_IN_IRAM
#define DAC_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
#define DAC_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif
/** /**
* @brief Register dac channel in the driver, in case a same channel is reused by different modes * @brief Register dac channel in the driver, in case a same channel is reused by different modes
* *
+4 -12
View File
@@ -12,6 +12,7 @@
* DAC digital controller clock source: I2S ws signal (root clock: D2PLL or APLL) * DAC digital controller clock source: I2S ws signal (root clock: D2PLL or APLL)
*/ */
#include "dac_priv_common.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@@ -19,15 +20,11 @@
#include "hal/i2s_types.h" #include "hal/i2s_types.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/i2s_periph.h" #include "hal/i2s_periph.h"
#include "../dac_priv_dma.h" #include "dac_priv_dma.h"
#include "esp_private/i2s_platform.h" #include "esp_private/i2s_platform.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#if CONFIG_DAC_ENABLE_DEBUG_LOG #include "esp_log.h"
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_check.h" #include "esp_check.h"
#include "esp_attr.h" #include "esp_attr.h"
@@ -42,8 +39,6 @@ typedef struct {
static dac_dma_periph_i2s_t *s_ddp = NULL; // Static DAC DMA peripheral structure pointer static dac_dma_periph_i2s_t *s_ddp = NULL; // Static DAC DMA peripheral structure pointer
static const char *TAG = "DAC_DMA";
static uint32_t s_dac_set_apll_freq(uint32_t mclk) static uint32_t s_dac_set_apll_freq(uint32_t mclk)
{ {
/* Calculate the expected APLL */ /* Calculate the expected APLL */
@@ -108,14 +103,11 @@ static esp_err_t s_dac_dma_periph_set_clock(uint32_t freq_hz, bool is_apll)
esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll) esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll)
{ {
#if CONFIG_DAC_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
/* Acquire DMA peripheral */ /* Acquire DMA peripheral */
ESP_RETURN_ON_ERROR(i2s_platform_acquire_occupation(I2S_CTLR_HP, DAC_DMA_PERIPH_I2S_NUM, "dac_dma"), TAG, "Failed to acquire DAC DMA peripheral"); ESP_RETURN_ON_ERROR(i2s_platform_acquire_occupation(I2S_CTLR_HP, DAC_DMA_PERIPH_I2S_NUM, "dac_dma"), TAG, "Failed to acquire DAC DMA peripheral");
/* Allocate DAC DMA peripheral object */ /* Allocate DAC DMA peripheral object */
s_ddp = (dac_dma_periph_i2s_t *)heap_caps_calloc(1, sizeof(dac_dma_periph_i2s_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); s_ddp = (dac_dma_periph_i2s_t *)heap_caps_calloc(1, sizeof(dac_dma_periph_i2s_t), DAC_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(s_ddp, ESP_ERR_NO_MEM, err, TAG, "No memory for DAC DMA object"); ESP_GOTO_ON_FALSE(s_ddp, ESP_ERR_NO_MEM, err, TAG, "No memory for DAC DMA object");
s_ddp->periph_dev = (void *)I2S_LL_GET_HW(DAC_DMA_PERIPH_I2S_NUM); s_ddp->periph_dev = (void *)I2S_LL_GET_HW(DAC_DMA_PERIPH_I2S_NUM);
+4 -12
View File
@@ -12,6 +12,7 @@
* DAC digital controller clock source: DIG_SARADC_CLK (root clock: APB or APLL) * DAC digital controller clock source: DIG_SARADC_CLK (root clock: APB or APLL)
*/ */
#include "dac_priv_common.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_private/spi_common_internal.h" #include "esp_private/spi_common_internal.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
@@ -24,13 +25,9 @@
#include "soc/lldesc.h" #include "soc/lldesc.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "../dac_priv_dma.h" #include "dac_priv_dma.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#if CONFIG_DAC_ENABLE_DEBUG_LOG #include "esp_log.h"
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_check.h" #include "esp_check.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
@@ -46,8 +43,6 @@ typedef struct {
static dac_dma_periph_spi_t *s_ddp = NULL; // Static DAC DMA peripheral structure pointer static dac_dma_periph_spi_t *s_ddp = NULL; // Static DAC DMA peripheral structure pointer
static const char *TAG = "DAC_DMA";
static uint32_t s_dac_set_apll_freq(uint32_t expt_freq) static uint32_t s_dac_set_apll_freq(uint32_t expt_freq)
{ {
/* Set APLL coefficients to the given frequency */ /* Set APLL coefficients to the given frequency */
@@ -125,15 +120,12 @@ static esp_err_t s_dac_dma_periph_set_clock(uint32_t freq_hz, bool is_apll)
esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll) esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll)
{ {
#if CONFIG_DAC_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
/* Acquire DMA peripheral */ /* Acquire DMA peripheral */
ESP_RETURN_ON_FALSE(spicommon_periph_claim(DAC_DMA_PERIPH_SPI_HOST, "dac_dma"), ESP_ERR_NOT_FOUND, TAG, "Failed to acquire DAC DMA peripheral"); ESP_RETURN_ON_FALSE(spicommon_periph_claim(DAC_DMA_PERIPH_SPI_HOST, "dac_dma"), ESP_ERR_NOT_FOUND, TAG, "Failed to acquire DAC DMA peripheral");
adc_apb_periph_claim(); adc_apb_periph_claim();
/* Allocate DAC DMA peripheral object */ /* Allocate DAC DMA peripheral object */
s_ddp = (dac_dma_periph_spi_t *)heap_caps_calloc(1, sizeof(dac_dma_periph_spi_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); s_ddp = (dac_dma_periph_spi_t *)heap_caps_calloc(1, sizeof(dac_dma_periph_spi_t), DAC_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(s_ddp, ESP_ERR_NO_MEM, err, TAG, "No memory for DAC DMA object"); ESP_GOTO_ON_FALSE(s_ddp, ESP_ERR_NO_MEM, err, TAG, "No memory for DAC DMA object");
s_ddp->periph_dev = (void *)SPI_LL_GET_HW(DAC_DMA_PERIPH_SPI_HOST); s_ddp->periph_dev = (void *)SPI_LL_GET_HW(DAC_DMA_PERIPH_SPI_HOST);