Merge branch 'refactor/driver_dac_common' into 'master'

refactor(dac): improve the DAC driver

See merge request espressif/esp-idf!48212
This commit is contained in:
Hu Rui
2026-07-01 13:36:23 +08:00
23 changed files with 927 additions and 488 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
@@ -49,7 +49,12 @@ static void dac_write_data_asynchronously(dac_continuous_handle_t handle, QueueH
/* Clear the legacy data in DMA, clear times equal to the 'dac_continuous_config_t::desc_num' */
for (int i = 0; i < 4; i++) {
xQueueReceive(que, &evt_data, portMAX_DELAY);
memset(evt_data.buf, 0, evt_data.buf_size);
/**
* NOTE: Directly manipulating the buffer is allowed, but please be aware of data layout and offset.
* Therefore, it is generally discouraged except in simple clearing cases.
* In this example, the audio data has a global offset of 0x80, so we write 0x80 to clear the buffer.
*/
memset(evt_data.buf, 0x80, evt_data.buf_size);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}

View File

@@ -30,6 +30,7 @@ static void dac_dma_write_task(void *args)
size_t buf_len = EXAMPLE_ARRAY_LEN;
while (1) {
ESP_LOGI(TAG, "%s wave start", wav_name[wav_sel]);
/* The wave in the buffer will be converted cyclically */
switch (wav_sel) {
case DAC_SINE_WAVE:
@@ -49,9 +50,9 @@ static void dac_dma_write_task(void *args)
}
/* Switch wave every CONFIG_EXAMPLE_WAVE_PERIOD_SEC seconds */
vTaskDelay(pdMS_TO_TICKS(CONFIG_EXAMPLE_WAVE_PERIOD_SEC * 1000));
ESP_ERROR_CHECK(dac_continuous_stop_cyclically(handle));
wav_sel++;
wav_sel %= DAC_WAVE_MAX;
ESP_LOGI(TAG, "%s wave start", wav_name[wav_sel]);
}
}

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@@ -7,18 +7,18 @@ from pytest_embedded_idf.utils import idf_parametrize
def test_dac_continuous_output(dut: Dut, mode: str, chan0_io: str, chan1_io: str) -> None:
dut.expect('dac continuous: --------------------------------------------------', timeout=10)
dut.expect('dac continuous: DAC continuous output by {}'.format(mode), timeout=10)
dut.expect('dac continuous: DAC channel 0 io: GPIO_NUM_{}'.format(chan0_io), timeout=10)
dut.expect('dac continuous: DAC channel 1 io: GPIO_NUM_{}'.format(chan1_io), timeout=10)
dut.expect(f'dac continuous: DAC continuous output by {mode}', timeout=10)
dut.expect(f'dac continuous: DAC channel 0 io: GPIO_NUM_{chan0_io}', timeout=10)
dut.expect(f'dac continuous: DAC channel 1 io: GPIO_NUM_{chan1_io}', timeout=10)
dut.expect('dac continuous: Waveform: SINE -> TRIANGLE -> SAWTOOTH -> SQUARE', timeout=10)
dut.expect('dac continuous: DAC conversion frequency \\(Hz\\): ([0-9]+)', timeout=10)
dut.expect('dac continuous: DAC wave frequency \\(Hz\\): ([0-9]+)', timeout=10)
dut.expect('dac continuous: --------------------------------------------------', timeout=10)
dut.expect(r'DAC channel 0 value:( +)(\d+)(.*)DAC channel 1 value:( +)(\d+)', timeout=10)
dut.expect(r'dac continuous\({}\): triangle wave start'.format(mode), timeout=20)
dut.expect(r'dac continuous\({}\): sawtooth wave start'.format(mode), timeout=20)
dut.expect(r'dac continuous\({}\): square wave start'.format(mode), timeout=20)
dut.expect(r'dac continuous\({}\): sine wave start'.format(mode), timeout=20)
dut.expect(rf'dac continuous\({mode}\): sine wave start', timeout=20)
dut.expect(rf'dac continuous\({mode}\): triangle wave start', timeout=20)
dut.expect(rf'dac continuous\({mode}\): sawtooth wave start', timeout=20)
dut.expect(rf'dac continuous\({mode}\): square wave start', timeout=20)
@pytest.mark.generic

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@@ -12,22 +12,12 @@ def test_dac_oneshot_example(dut: Dut) -> None:
for _ in range(10):
res.append(dut.expect(r'DAC channel 0 value:( +)(\d+)(.*)DAC channel 1 value:( +)(\d+)', timeout=10))
avg1_ch1 = 0
avg1_ch2 = 0
avg2_ch1 = 0
avg2_ch2 = 0
avg1_ch0 = sum(int(val.group(2)) for val in res[0:5]) / 5
avg1_ch1 = sum(int(val.group(5)) for val in res[0:5]) / 5
avg2_ch0 = sum(int(val.group(2)) for val in res[5:10]) / 5
avg2_ch1 = sum(int(val.group(5)) for val in res[5:10]) / 5
for val in res[0:5]:
avg1_ch1 = avg1_ch1 + int(val.group(2))
avg1_ch2 = avg1_ch2 + int(val.group(5))
for val in res[5:10]:
avg2_ch1 = avg1_ch1 + int(val.group(2))
avg2_ch2 = avg1_ch2 + int(val.group(5))
avg1_ch1 = int(avg1_ch1 / 5)
avg1_ch2 = int(avg1_ch2 / 5)
avg2_ch1 = int(avg2_ch1 / 5)
avg2_ch2 = int(avg2_ch2 / 5)
assert avg2_ch1 > avg1_ch1
assert avg2_ch2 > avg1_ch2
assert avg2_ch0 > avg1_ch0
# On ESP32-S2 CI runners, GPIO18 (DAC ch1) has an LED attached. The voltage is clamped.
if dut.target != 'esp32s2':
assert avg2_ch1 > avg1_ch1