mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
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:
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user