Merge branch 'refactor/remove_legacy_dac_driver' into 'master'

remove(legacy_dac): remove legacy dac driver in IDF v6.0

Closes IDF-13344

See merge request espressif/esp-idf!39682
This commit is contained in:
Kevin (Lao Kaiyao)
2025-06-13 19:42:27 +08:00
26 changed files with 23 additions and 910 deletions

View File

@ -25,12 +25,6 @@ if(CONFIG_SOC_ADC_SUPPORTED)
endif()
endif()
# DAC related source files
if(CONFIG_SOC_DAC_SUPPORTED)
list(APPEND srcs "deprecated/dac_common_legacy.c"
"deprecated/${target}/dac_legacy.c")
endif()
# I2C related source files
if(CONFIG_SOC_I2C_SUPPORTED)
list(APPEND srcs "i2c/i2c.c")

View File

@ -68,23 +68,6 @@ menu "Driver Configurations"
endmenu # Legacy ADC Calibration Configuration
endmenu # Legacy ADC Driver Configuration
menu "Legacy DAC Driver Configurations"
depends on SOC_DAC_SUPPORTED
config DAC_SUPPRESS_DEPRECATE_WARN
bool "Suppress legacy driver deprecated warning"
default n
help
Whether to suppress the deprecation warnings when using legacy dac driver (driver/dac.h).
If you want to continue using the legacy driver, and don't want to see related deprecation warnings,
you can enable this option.
config DAC_SKIP_LEGACY_CONFLICT_CHECK
bool "Skip legacy conflict check"
default n
help
This configuration option allows the user to bypass the conflict check mechanism with legacy code.
endmenu # Legacy DAC Driver Configurations
menu "Legacy MCPWM Driver Configurations"
depends on SOC_MCPWM_SUPPORTED
config MCPWM_SUPPRESS_DEPRECATE_WARN

View File

@ -1,144 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/gpio.h"
#include "driver/dac_types_legacy.h"
#include "soc/dac_periph.h"
#include "hal/gpio_types.h"
#include "hal/dac_ll.h"
#include "clk_ctrl_os.h"
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
static __attribute__((unused)) const char *TAG = "DAC";
/*---------------------------------------------------------------
DAC
---------------------------------------------------------------*/
esp_err_t dac_pad_get_io_num(dac_channel_t channel, gpio_num_t *gpio_num)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
*gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[channel];
return ESP_OK;
}
static esp_err_t dac_rtc_pad_init(dac_channel_t channel)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
gpio_num_t gpio_num = 0;
dac_pad_get_io_num(channel, &gpio_num);
gpio_config_as_analog(gpio_num);
return ESP_OK;
}
esp_err_t dac_output_enable(dac_channel_t channel)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
dac_rtc_pad_init(channel);
portENTER_CRITICAL(&rtc_spinlock);
dac_ll_power_on(channel);
dac_ll_rtc_sync_by_adc(false);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_output_disable(dac_channel_t channel)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
portENTER_CRITICAL(&rtc_spinlock);
dac_ll_power_down(channel);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_output_voltage(dac_channel_t channel, uint8_t dac_value)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
portENTER_CRITICAL(&rtc_spinlock);
dac_ll_update_output_value(channel, dac_value);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value)
{
ESP_RETURN_ON_FALSE(channel < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "DAC channel error");
portENTER_CRITICAL(&rtc_spinlock);
dac_ll_update_output_value(channel, dac_value);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_cw_generator_enable(void)
{
portENTER_CRITICAL(&rtc_spinlock);
periph_rtc_dig_clk8m_enable();
dac_ll_cw_generator_enable();
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_cw_generator_disable(void)
{
portENTER_CRITICAL(&rtc_spinlock);
dac_ll_cw_generator_disable();
periph_rtc_dig_clk8m_disable();
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t dac_cw_generator_config(dac_cw_config_t *cw)
{
ESP_RETURN_ON_FALSE(cw, ESP_ERR_INVALID_ARG, TAG, "invalid clock configuration");
portENTER_CRITICAL(&rtc_spinlock);
/* Enable the rtc8m clock temporary to get the correct frequency */
periph_rtc_dig_clk8m_enable();
uint32_t rtc_freq = periph_rtc_dig_clk8m_get_freq();
periph_rtc_dig_clk8m_disable();
dac_ll_cw_set_freq(cw->freq, rtc_freq);
dac_ll_cw_set_atten(cw->en_ch, (dac_cosine_atten_t)cw->scale);
dac_ll_cw_set_phase(cw->en_ch, (dac_cosine_phase_t)cw->phase);
dac_ll_cw_set_dc_offset(cw->en_ch, cw->offset);
dac_ll_cw_enable_channel(cw->en_ch, true);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
#if !CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK
/**
* @brief This function will be called during start up, to check that this legacy DAC driver is not running along with the new driver
*/
__attribute__((constructor))
static void check_dac_legacy_driver_conflict(void)
{
// This function was declared as weak here. The new DAC driver has one implementation.
// So if the new DAC driver is not linked in, then `dac_priv_register_channel()` should be NULL at runtime.
extern __attribute__((weak)) esp_err_t dac_priv_register_channel(dac_channel_t chan_id, const char *mode_name);
if ((void *)dac_priv_register_channel != NULL) {
ESP_EARLY_LOGE(TAG, "CONFLICT! The new DAC driver is not allowed to be used together with the legacy driver");
abort();
}
ESP_EARLY_LOGW(TAG, "legacy driver is deprecated, please migrate to `driver/dac_oneshot.h`, `driver/dac_cosine.h` or `driver/dac_continuous.h` instead");
}
#endif //CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK

View File

@ -1,171 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "driver/dac_types_legacy.h"
#if !CONFIG_DAC_SUPPRESS_DEPRECATE_WARN
#warning "The legacy DAC driver is deprecated, please use `driver/dac_oneshot.h`, `driver/dac_cosine.h` or `driver/dac_continuous.h` instead"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get the GPIO number of a specific DAC channel.
*
* @param channel Channel to get the gpio number
* @param gpio_num output buffer to hold the gpio number
* @return
* - ESP_OK if success
*/
esp_err_t dac_pad_get_io_num(dac_channel_t channel, gpio_num_t *gpio_num);
/**
* @brief Set DAC output voltage.
* DAC output is 8-bit. Maximum (255) corresponds to VDD3P3_RTC.
*
* @note Need to configure DAC pad before calling this function.
* DAC channel 0 is attached to GPIO25, DAC channel 1 is attached to GPIO26
* @param channel DAC channel
* @param dac_value DAC output value
*
* @return
* - ESP_OK success
*/
esp_err_t dac_output_voltage(dac_channel_t channel, uint8_t dac_value);
/**
* @brief DAC pad output enable
*
* @param channel DAC channel
* @note DAC channel 0 is attached to GPIO25, DAC channel 1 is attached to GPIO26
* I2S left channel will be mapped to DAC channel 1
* I2S right channel will be mapped to DAC channel 0
*/
esp_err_t dac_output_enable(dac_channel_t channel);
/**
* @brief DAC pad output disable
*
* @param channel DAC channel
* @note DAC channel 0 is attached to GPIO25, DAC channel 1 is attached to GPIO26
* @return
* - ESP_OK success
*/
esp_err_t dac_output_disable(dac_channel_t channel);
/**
* @brief Enable cosine wave generator output.
*
* @return
* - ESP_OK success
*/
esp_err_t dac_cw_generator_enable(void);
/**
* @brief Disable cosine wave generator output.
*
* @return
* - ESP_OK success
*/
esp_err_t dac_cw_generator_disable(void);
/**
* @brief Config the cosine wave generator function in DAC module.
*
* @param cw Configuration.
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG The parameter is NULL.
*/
esp_err_t dac_cw_generator_config(dac_cw_config_t *cw);
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
#if CONFIG_IDF_TARGET_ESP32
/**
* @brief Enable DAC output data from I2S
*
* @return
* - ESP_OK success
*/
esp_err_t dac_i2s_enable(void);
/**
* @brief Disable DAC output data from I2S
*
* @return
* - ESP_OK success
*/
esp_err_t dac_i2s_disable(void);
#endif // CONFIG_IDF_TARGET_ESP32
#if CONFIG_IDF_TARGET_ESP32S2
/**
* @brief DAC digital controller initialization.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_init(void);
/**
* @brief DAC digital controller deinitialization.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_deinit(void);
/**
* @brief Setting the DAC digital controller.
*
* @param cfg Pointer to digital controller parameter. See ``dac_digi_config_t``.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg);
/**
* @brief DAC digital controller start output voltage.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_start(void);
/**
* @brief DAC digital controller stop output voltage.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_stop(void);
/**
* @brief Reset DAC digital controller FIFO.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_fifo_reset(void);
/**
* @brief Reset DAC digital controller.
* @return
* - ESP_OK success
*/
esp_err_t dac_digi_reset(void);
#endif // CONFIG_IDF_TARGET_ESP32S2
#ifdef __cplusplus
}
#endif

View File

@ -1,79 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include "sdkconfig.h"
#include "hal/dac_types.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "hal/adc_types.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The multiple of the amplitude of the cosine wave generator. The max amplitude is VDD3P3_RTC.
*/
typedef enum {
DAC_CW_SCALE_1 = 0x0, /*!< 1/1. Default. */
DAC_CW_SCALE_2 = 0x1, /*!< 1/2. */
DAC_CW_SCALE_4 = 0x2, /*!< 1/4. */
DAC_CW_SCALE_8 = 0x3, /*!< 1/8. */
} dac_cw_scale_t;
/**
* @brief Set the phase of the cosine wave generator output.
*/
typedef enum {
DAC_CW_PHASE_0 = 0x2, /*!< Phase shift +0° */
DAC_CW_PHASE_180 = 0x3, /*!< Phase shift +180° */
} dac_cw_phase_t;
#if CONFIG_IDF_TARGET_ESP32S2
/**
* @brief DAC digital controller (DMA mode) work mode.
*/
typedef enum {
DAC_CONV_NORMAL, /*!< The data in the DMA buffer is simultaneously output to the enable channel of the DAC. */
DAC_CONV_ALTER, /*!< The data in the DMA buffer is alternately output to the enable channel of the DAC. */
DAC_CONV_MAX
} dac_digi_convert_mode_t;
/**
* @brief DAC digital controller (DMA mode) configuration parameters.
*/
typedef struct {
dac_digi_convert_mode_t mode; /*!<DAC digital controller (DMA mode) work mode. See ``dac_digi_convert_mode_t``. */
uint32_t interval; /*!<The number of interval clock cycles for the DAC digital controller to output voltage.
The unit is the divided clock. Range: 1 ~ 4095.
Expression: `dac_output_freq` = `controller_clk` / interval. Refer to ``adc_digi_clk_t``.
Note: The sampling rate of each channel is also related to the conversion mode (See ``dac_digi_convert_mode_t``) and pattern table settings. */
adc_digi_clk_t dig_clk; /*!<DAC digital controller clock divider settings. Refer to ``adc_digi_clk_t``.
Note: The clocks of the DAC digital controller use the ADC digital controller clock divider. */
} dac_digi_config_t;
#endif
/**
* @brief Config the cosine wave generator function in DAC module.
*/
typedef struct {
dac_channel_t en_ch; /*!< Enable the cosine wave generator of DAC channel. */
dac_cw_scale_t scale; /*!< Set the amplitude of the cosine wave generator output. */
dac_cw_phase_t phase; /*!< Set the phase of the cosine wave generator output. */
uint32_t freq; /*!< Set frequency of cosine wave generator output. Range: 130(130Hz) ~ 55000(100KHz). */
int8_t offset; /*!< Set the voltage value of the DC component of the cosine wave generator output.
Note: Unreasonable settings can cause waveform to be oversaturated. Range: -128 ~ 127. */
} dac_cw_config_t;
#ifdef __cplusplus
}
#endif

View File

@ -1,35 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "hal/dac_ll.h"
#include "esp_err.h"
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
#define DAC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define DAC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
esp_err_t dac_i2s_enable(void)
{
DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(true);
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_i2s_disable(void)
{
DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(false);
DAC_EXIT_CRITICAL();
return ESP_OK;
}

View File

@ -1,135 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "driver/dac_types_legacy.h"
#include "hal/adc_ll.h"
#include "hal/dac_ll.h"
#include "esp_check.h"
#include "esp_pm.h"
static __attribute__((unused)) const char *TAG = "DAC";
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
#define DAC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define DAC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
#ifdef CONFIG_PM_ENABLE
static esp_pm_lock_handle_t s_dac_digi_lock = NULL;
#endif //CONFIG_PM_ENABLE
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
esp_err_t dac_digi_init(void)
{
DAC_ENTER_CRITICAL();
dac_ll_digi_clk_inv(true);
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_deinit(void)
{
#ifdef CONFIG_PM_ENABLE
if (s_dac_digi_lock) {
esp_pm_lock_delete(s_dac_digi_lock);
s_dac_digi_lock = NULL;
}
#endif
DAC_ENTER_CRITICAL();
dac_ll_digi_trigger_output(false);
dac_ll_digi_enable_dma(false);
dac_ll_digi_fifo_reset();
dac_ll_digi_reset();
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg)
{
ESP_RETURN_ON_FALSE(cfg->mode <= DAC_CONV_ALTER, ESP_ERR_INVALID_ARG, TAG, "DAC mode error");
ESP_RETURN_ON_FALSE(cfg->interval > 0 && cfg->interval < 4096, ESP_ERR_INVALID_ARG, TAG, "DAC interval error");
ESP_RETURN_ON_FALSE(cfg->dig_clk.div_num < 256, ESP_ERR_INVALID_ARG, TAG, "DAC clk div_num error");
ESP_RETURN_ON_FALSE(cfg->dig_clk.div_b > 0 && cfg->dig_clk.div_b < 64, ESP_ERR_INVALID_ARG, TAG, "DAC clk div_b error");
ESP_RETURN_ON_FALSE(cfg->dig_clk.div_a < 64, ESP_ERR_INVALID_ARG, TAG, "DAC clk div_a error");
#ifdef CONFIG_PM_ENABLE
esp_err_t err;
if (s_dac_digi_lock == NULL) {
if (cfg->dig_clk.use_apll) {
err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "dac_dma", &s_dac_digi_lock);
} else {
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "dac_dma", &s_dac_digi_lock);
}
if (err != ESP_OK) {
s_dac_digi_lock = NULL;
ESP_LOGE(TAG, "DAC-DMA pm lock error");
return err;
}
}
#endif //CONFIG_PM_ENABLE
DAC_ENTER_CRITICAL();
dac_ll_digi_set_convert_mode(cfg->mode == DAC_CONV_ALTER);
dac_ll_digi_set_trigger_interval(cfg->interval);
adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a);
adc_ll_digi_clk_sel(cfg->dig_clk.use_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT);
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_start(void)
{
#ifdef CONFIG_PM_ENABLE
ESP_RETURN_ON_FALSE(s_dac_digi_lock, ESP_FAIL, TAG, "Should start after call `dac_digi_controller_config`");
esp_pm_lock_acquire(s_dac_digi_lock);
#endif
DAC_ENTER_CRITICAL();
dac_ll_digi_enable_dma(true);
dac_ll_digi_trigger_output(true);
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_stop(void)
{
#ifdef CONFIG_PM_ENABLE
if (s_dac_digi_lock) {
esp_pm_lock_release(s_dac_digi_lock);
}
#endif
DAC_ENTER_CRITICAL();
dac_ll_digi_trigger_output(false);
dac_ll_digi_enable_dma(false);
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_fifo_reset(void)
{
DAC_ENTER_CRITICAL();
dac_ll_digi_fifo_reset();
DAC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t dac_digi_reset(void)
{
DAC_ENTER_CRITICAL();
dac_ll_digi_reset();
DAC_EXIT_CRITICAL();
return ESP_OK;
}

View File

@ -1,11 +1,5 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/driver/test_apps/dac_test_apps/legacy_dac_driver:
disable:
- if: SOC_DAC_SUPPORTED != 1
depends_components:
- esp_adc
components/driver/test_apps/legacy_adc_driver:
disable:
- if: SOC_ADC_SUPPORTED != 1

View File

@ -1,21 +0,0 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(dac_legacy_test)
if(CONFIG_COMPILER_DUMP_RTL_FILES)
add_custom_target(check_test_app_sections ALL
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
--elf-file ${CMAKE_BINARY_DIR}/dac_legacy_test.elf
find-refs
--from-sections=.iram0.text
--to-sections=.flash.text,.flash.rodata
--exit-code
DEPENDS ${elf}
)
endif()

View File

@ -1,2 +0,0 @@
| Supported Targets | ESP32 | ESP32-S2 |
| ----------------- | ----- | -------- |

View File

@ -1,8 +0,0 @@
set(srcs "test_app_main.c"
"test_legacy_dac.c")
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity driver esp_event esp_adc
WHOLE_ARCHIVE)

View File

@ -1,53 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_heap_caps.h"
// Some resources are lazy allocated in dac driver, the threshold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (-300)
static size_t before_free_8bit;
static size_t before_free_32bit;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
}
void app_main(void)
{
// ____ _ ____ _____ _
// | _ \ / \ / ___| |_ _|__ ___| |_
// | | | |/ _ \| | | |/ _ \/ __| __|
// | |_| / ___ \ |___ | | __/\__ \ |_
// |____/_/ \_\____| |_|\___||___/\__|
printf(" ____ _ ____ _____ _ \n");
printf(" | _ \\ / \\ / ___| |_ _|__ ___| |_ \n");
printf(" | | | |/ _ \\| | | |/ _ \\/ __| __|\n");
printf(" | |_| / ___ \\ |___ | | __/\\__ \\ |_ \n");
printf(" |____/_/ \\_\\____| |_|\\___||___/\\__| (legacy)\n");
unity_run_menu();
}

View File

@ -1,183 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
Tests for the dac device driver
*/
#include <inttypes.h>
#include "esp_system.h"
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "soc/soc_caps.h"
#define CONFIG_ADC_SUPPRESS_DEPRECATE_WARN 1
#include "driver/adc.h"
#include "driver/dac.h"
#include "esp_adc_cal.h"
static const char *TAG = "test_dac";
#ifdef CONFIG_IDF_TARGET_ESP32
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_12
#elif defined CONFIG_IDF_TARGET_ESP32S2
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
#endif
#define ADC_TEST_ATTEN ADC_ATTEN_DB_12
#if CONFIG_IDF_TARGET_ESP32
#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25
#define DAC_TEST_CHANNEL_NUM DAC_CHAN_0 // GPIO25
#elif CONFIG_IDF_TARGET_ESP32S2
#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_6 // GPIO17
#define DAC_TEST_CHANNEL_NUM DAC_CHAN_0 // GPIO17
#endif
#define DAC_OUT_MAX (200)
#define DAC_OUT_TIMES (10)
#define DAC_OUT_STEP (DAC_OUT_MAX / DAC_OUT_TIMES)
#define DAC_TEST_TIMES (100)
TEST_CASE("DAC_output(RTC)_check_by_adc", "[dac_legacy]")
{
gpio_num_t adc_gpio_num, dac_gpio_num;
TEST_ESP_OK(adc2_pad_get_io_num(ADC_TEST_CHANNEL_NUM, &adc_gpio_num));
TEST_ESP_OK(dac_pad_get_io_num(DAC_TEST_CHANNEL_NUM, &dac_gpio_num));
printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num);
TEST_ESP_OK(dac_output_enable(DAC_TEST_CHANNEL_NUM));
//be sure to do the init before using adc2.
printf("adc2_init...\n");
TEST_ESP_OK(adc2_config_channel_atten(ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN));
vTaskDelay(2 * portTICK_PERIOD_MS);
printf("start conversion.\n");
int output_data = 0;
int read_raw = 0, read_old = 0;
for (int i = 0; i < DAC_OUT_TIMES; i++) {
TEST_ESP_OK(dac_output_voltage(DAC_TEST_CHANNEL_NUM, output_data));
output_data += DAC_OUT_STEP;
vTaskDelay(2 * portTICK_PERIOD_MS);
TEST_ESP_OK(adc2_get_raw(ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw));
ESP_LOGI(TAG, "DAC: %d - ADC: %d", output_data, read_raw);
if (read_old != 0) {
TEST_ASSERT_GREATER_THAN(read_old, read_raw);
}
read_old = read_raw;
}
TEST_ESP_OK(dac_output_disable(DAC_TEST_CHANNEL_NUM));
}
TEST_CASE("DAC_cw_generator_output(RTC)_check_by_adc", "[dac_legacy]")
{
gpio_num_t adc_gpio_num, dac_gpio_num;
TEST_ESP_OK(adc2_pad_get_io_num(ADC_TEST_CHANNEL_NUM, &adc_gpio_num));
TEST_ESP_OK(dac_pad_get_io_num(DAC_TEST_CHANNEL_NUM, &dac_gpio_num));
printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num);
dac_cw_config_t cw = {
.en_ch = DAC_TEST_CHANNEL_NUM,
.scale = DAC_CW_SCALE_2,
.phase = DAC_CW_PHASE_0,
.freq = 1000,
#if CONFIG_IDF_TARGET_ESP32
.offset = 64,
#elif CONFIG_IDF_TARGET_ESP32S2
.offset = 16,
#endif
};
TEST_ESP_OK(dac_cw_generator_config(&cw));
TEST_ESP_OK(dac_cw_generator_enable());
TEST_ESP_OK(dac_output_enable(DAC_TEST_CHANNEL_NUM));
//be sure to do the init before using adc2.
printf("adc2_init...\n");
TEST_ESP_OK(adc2_config_channel_atten(ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN));
vTaskDelay(2 * portTICK_PERIOD_MS);
printf("start conversion.\n");
int read_raw[3] = {0};
for (int i = 0; i < DAC_TEST_TIMES; i++) {
vTaskDelay(10 * portTICK_PERIOD_MS);
TEST_ESP_OK(adc2_get_raw(ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw[0]));
ESP_LOGI(TAG, "ADC: %d", read_raw[0]);
read_raw[2] = read_raw[1];
read_raw[1] = read_raw[0];
}
TEST_ESP_OK(dac_cw_generator_disable());
TEST_ESP_OK(dac_output_disable(DAC_TEST_CHANNEL_NUM));
}
#if CONFIG_IDF_TARGET_ESP32S2
static int helper_calc_dac_output(int mV)
{
return mV * 0.07722;
}
static bool subtest_adc_dac(int mV_ref, esp_adc_cal_characteristics_t * chars)
{
dac_output_voltage(DAC_TEST_CHANNEL_NUM, helper_calc_dac_output(mV_ref));
vTaskDelay(pdMS_TO_TICKS(80));
int raw;
adc2_get_raw((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_WIDTH_BIT_13, &raw);
uint32_t voltage = esp_adc_cal_raw_to_voltage(raw, chars);
TEST_ASSERT_INT_WITHIN(200, mV_ref, voltage); // 200 mV error allowance, because both DAC and ADC have error
return true;
}
TEST_CASE("esp32s2_adc2-dac_with_adc2_calibration", "[dac_legacy]")
{
gpio_num_t adc_gpio_num, dac_gpio_num;
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) != ESP_OK) {
TEST_IGNORE_MESSAGE("Warning: This esp32s2 board does not support calibration. This test will be skipped.\n");
}
TEST_ESP_OK(adc2_pad_get_io_num(ADC_TEST_CHANNEL_NUM, &adc_gpio_num));
TEST_ESP_OK(dac_pad_get_io_num(DAC_TEST_CHANNEL_NUM, &dac_gpio_num));
printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num);
TEST_ESP_OK(dac_output_enable(DAC_TEST_CHANNEL_NUM));
esp_adc_cal_characteristics_t chars;
printf("Test 0dB atten...\n");
adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_0);
esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_13, 0, &chars);
printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b);
subtest_adc_dac(750, &chars);
printf("Test 2.5dB atten...\n");
adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_2_5);
esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_2_5, ADC_WIDTH_BIT_13, 0, &chars);
printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b);
subtest_adc_dac(1100, &chars);
printf("Test 6dB atten...\n");
adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_6);
esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_13, 0, &chars);
printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b);
subtest_adc_dac(800, &chars);
subtest_adc_dac(1250, &chars);
printf("Test 11dB atten...\n");
adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_12);
esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_13, 0, &chars);
printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b);
subtest_adc_dac(1500, &chars);
subtest_adc_dac(2500, &chars);
}
#endif

View File

@ -1,18 +0,0 @@
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'release',
],
indirect=True,
)
@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target'])
def test_legacy_dac(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@ -1,5 +0,0 @@
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@ -1,4 +0,0 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n
CONFIG_ADC_DISABLE_DAC=n
CONFIG_DAC_SUPPRESS_DEPRECATE_WARN=y

View File

@ -573,10 +573,6 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
return clk_freq;
}
/* Temporary ignore the deprecated warning of i2s_event_data_t::data */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#if SOC_GDMA_SUPPORTED
static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
{
@ -592,7 +588,6 @@ static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_e
esp_cache_msync((void *)finish_desc->buf, handle->dma.buf_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE);
#endif
i2s_event_data_t evt = {
.data = &(finish_desc->buf),
.dma_buf = (void *)finish_desc->buf,
.size = handle->dma.buf_size,
};
@ -602,7 +597,6 @@ static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_e
if (xQueueIsQueueFullFromISR(handle->msg_queue)) {
xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1);
if (handle->callbacks.on_recv_q_ovf) {
evt.data = NULL;
user_need_yield |= handle->callbacks.on_recv_q_ovf(handle, &evt, handle->user_data);
}
}
@ -623,7 +617,6 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e
finish_desc = (lldesc_t *)event_data->tx_eof_desc_addr;
void *curr_buf = (void *)finish_desc->buf;
i2s_event_data_t evt = {
.data = &(finish_desc->buf),
.dma_buf = curr_buf,
.size = handle->dma.buf_size,
};
@ -642,7 +635,6 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e
if (xQueueIsQueueFullFromISR(handle->msg_queue)) {
xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1);
if (handle->callbacks.on_send_q_ovf) {
evt.data = NULL;
evt.dma_buf = NULL;
user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data);
}
@ -678,7 +670,6 @@ static void IRAM_ATTR i2s_dma_rx_callback(void *arg)
if (handle && (status & I2S_LL_EVENT_RX_EOF)) {
i2s_hal_get_in_eof_des_addr(&(handle->controller->hal), (uint32_t *)&finish_desc);
evt.data = &(finish_desc->buf);
evt.dma_buf = (void *)finish_desc->buf;
evt.size = handle->dma.buf_size;
if (handle->callbacks.on_recv) {
@ -687,7 +678,6 @@ static void IRAM_ATTR i2s_dma_rx_callback(void *arg)
if (xQueueIsQueueFullFromISR(handle->msg_queue)) {
xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1);
if (handle->callbacks.on_recv_q_ovf) {
evt.data = NULL;
evt.dma_buf = NULL;
user_need_yield |= handle->callbacks.on_recv_q_ovf(handle, &evt, handle->user_data);
}
@ -719,7 +709,6 @@ static void IRAM_ATTR i2s_dma_tx_callback(void *arg)
if (handle && (status & I2S_LL_EVENT_TX_EOF)) {
i2s_hal_get_out_eof_des_addr(&(handle->controller->hal), (uint32_t *)&finish_desc);
void *curr_buf = (void *)finish_desc->buf;
evt.data = &(finish_desc->buf);
evt.dma_buf = curr_buf;
evt.size = handle->dma.buf_size;
// Auto clear the dma buffer before data sent
@ -732,7 +721,6 @@ static void IRAM_ATTR i2s_dma_tx_callback(void *arg)
if (xQueueIsQueueFullFromISR(handle->msg_queue)) {
xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1);
if (handle->callbacks.on_send_q_ovf) {
evt.data = NULL;
user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data);
}
}
@ -749,8 +737,6 @@ static void IRAM_ATTR i2s_dma_tx_callback(void *arg)
}
#endif
#pragma GCC diagnostic pop
#if SOC_GDMA_SUPPORTED
/**
* @brief I2S DMA interrupt initialization (implemented by I2S dedicated DMA)

View File

@ -75,9 +75,6 @@ typedef struct {
* @brief Event structure used in I2S event queue
*/
typedef struct {
void *data __attribute__((deprecated)); /**< (Deprecated) The secondary pointer of DMA buffer that just finished sending or receiving for `on_recv` and `on_sent` callback
* NULL for `on_recv_q_ovf` and `on_send_q_ovf` callback
*/
void *dma_buf;/**< The first level pointer of DMA buffer that just finished sending or receiving for `on_recv` and `on_sent` callback
* NULL for `on_recv_q_ovf` and `on_send_q_ovf` callback
*/

View File

@ -7,8 +7,6 @@ extern "C" {
typedef enum {
DAC_CHAN_0 = 0, /*!< DAC channel 0 is GPIO25(ESP32) / GPIO17(ESP32S2) */
DAC_CHAN_1 = 1, /*!< DAC channel 1 is GPIO26(ESP32) / GPIO18(ESP32S2) */
DAC_CHANNEL_1 __attribute__((deprecated("please use 'DAC_CHAN_0' instead"))) = 0, /*!< Alias of 'DAC_CHAN_0', now the channel index start from '0' */
DAC_CHANNEL_2 __attribute__((deprecated("please use 'DAC_CHAN_1' instead"))) = 1, /*!< Alias of 'DAC_CHAN_1', now the channel index start from '0' */
} dac_channel_t;
/**

View File

@ -120,7 +120,6 @@ Kconfig Options
^^^^^^^^^^^^^^^
- :ref:`CONFIG_DAC_ISR_IRAM_SAFE` controls whether the default ISR handler can work when cache is disabled. See `IRAM Safe <#iram-safe>`__ for more information.
- :ref:`CONFIG_DAC_SUPPRESS_DEPRECATE_WARN` controls whether to suppress the warning message compilation while using the legacy DAC driver.
- :ref:`CONFIG_DAC_ENABLE_DEBUG_LOG` is used to enable the debug log output. Enable this option increases the firmware binary size.
.. only:: esp32

View File

@ -5,10 +5,12 @@ Peripherals
.. only:: SOC_DAC_SUPPORTED
.. _deprecate_dac_legacy_driver:
DAC
---
DAC driver has been redesigned (see :doc:`DAC API Reference <../../../api-reference/peripherals/dac>`), which aims to unify the interface and extend the usage of DAC peripheral. Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/dac.h``. However, by default, including ``driver/dac.h`` will bring a build warning like ``The legacy DAC driver is deprecated, please use 'driver/dac_oneshot.h', 'driver/dac_cosine.h' or 'driver/dac_continuous.h' instead``. The warning can be suppressed by the Kconfig option :ref:`CONFIG_DAC_SUPPRESS_DEPRECATE_WARN`.
DAC driver has been redesigned (see :doc:`DAC API Reference <../../../api-reference/peripherals/dac>`), which aims to unify the interface and extend the usage of DAC peripheral. Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/dac.h``. However, by default, including ``driver/dac.h`` will bring a build warning like ``The legacy DAC driver is deprecated, please use 'driver/dac_oneshot.h', 'driver/dac_cosine.h' or 'driver/dac_continuous.h' instead``. The warning can be suppressed by the Kconfig option ``CONFIG_DAC_SUPPRESS_DEPRECATE_WARN``.
The major breaking changes in concept and usage are listed as follows:

View File

@ -81,3 +81,10 @@ SDMMC
-----
- The ``get_dma_info`` member in the :cpp:type:`sdmmc_host_t` structure, as well as the ``sdspi_host_get_dma_info`` and ``sdmmc_host_get_dma_info`` functions, have been removed. DMA configuration is now handled internally by the driver.
.. only:: SOC_DAC_SUPPORTED
Legacy DAC Driver is Removed
------------------------------------
The legacy DAC driver ``driver/dac.h`` is deprecated since version 5.1 (see :ref:`deprecate_dac_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_dac`, and the header file path is ``driver/dac_oneshot.h``, ``driver/dac_continuous.h`` and ``driver/dac_cosine.h``.

View File

@ -120,7 +120,6 @@ Kconfig 选项
^^^^^^^^^^^^^
- :ref:`CONFIG_DAC_ISR_IRAM_SAFE` 控制默认 ISR 处理程序在 cache 被禁用时能否继续运行。更多信息可参考 `IRAM 安全 <#iram-safe>`__
- :ref:`CONFIG_DAC_SUPPRESS_DEPRECATE_WARN` 控制是否在使用原有 DAC 驱动时关闭警告信息。
- :ref:`CONFIG_DAC_ENABLE_DEBUG_LOG` 用于启用调试日志输出。启用该选项将增加固件的二进制文件大小。
.. only:: esp32

View File

@ -5,10 +5,12 @@
.. only:: SOC_DAC_SUPPORTED
.. _deprecate_dac_legacy_driver:
DAC
---
DAC 驱动程序已经过重新设计(参考 :doc:`DAC API 参考 <../../../api-reference/peripherals/dac>`),以统一接口并扩展 DAC 外设的使用。建议使用更新后的驱动 API但用户仍然可以通过包含路径 ``driver/dac.h`` 使用原有驱动。然而默认情况下,在文件中包含 ``driver/dac.h`` 会引发构建警告,例如 ``The legacy DAC driver is deprecated, please use 'driver/dac_oneshot.h', 'driver/dac_cosine.h' or 'driver/dac_continuous.h' instead``。可通过 Kconfig 选项 :ref:`CONFIG_DAC_SUPPRESS_DEPRECATE_WARN` 关闭该警告。
DAC 驱动程序已经过重新设计(参考 :doc:`DAC API 参考 <../../../api-reference/peripherals/dac>`),以统一接口并扩展 DAC 外设的使用。建议使用更新后的驱动 API但用户仍然可以通过包含路径 ``driver/dac.h`` 使用原有驱动。然而默认情况下,在文件中包含 ``driver/dac.h`` 会引发构建警告,例如 ``The legacy DAC driver is deprecated, please use 'driver/dac_oneshot.h', 'driver/dac_cosine.h' or 'driver/dac_continuous.h' instead``。可通过 Kconfig 选项 ``CONFIG_DAC_SUPPRESS_DEPRECATE_WARN`` 关闭该警告。
主要概念和使用方法上的更新如下所示:

View File

@ -81,3 +81,10 @@ SDMMC
-----
- :cpp:type:`sdmmc_host_t` 结构体中的 ``get_dma_info`` 成员接口已经被移除。对应的 ``sdspi_host_get_dma_info````sdmmc_host_get_dma_info`` 函数也已经被移除。DMA 相关的设置会由驱动内部处理好。
.. only:: SOC_DAC_SUPPORTED
旧版 DAC 驱动被移除
----------------------
旧版的 DAC 驱动 ``driver/dac.h`` 在 5.1 的版本中就已经被弃用(请参考 :ref:`deprecate_dac_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_dac` 组件中,头文件引用路径为 ``driver/dac_oneshot.h`` ``driver/dac_continuous.h````driver/dac_cosine.h``

View File

@ -506,3 +506,6 @@
-
re_variables: ['driver/pcnt.h']
hint_variables: ['legacy pcnt', 'driver/pulse_cnt.h', 'esp_driver_pcnt']
-
re_variables: ['driver/dac.h']
hint_variables: ['legacy DAC', 'driver/dac_oneshot.h, driver/dac_continuous.h, driver/dac_cosine.h', 'esp_driver_dac']