Skip to content

Commit

Permalink
Merge branch 'feature/dac_driver_ng' into 'master'
Browse files Browse the repository at this point in the history
🔨 DAC: driver NG

Closes IDF-4742

See merge request espressif/esp-idf!18097
  • Loading branch information
L-KAYA committed Oct 25, 2022
2 parents 8e9b1e8 + 8ef9fd4 commit 9bc2d15
Show file tree
Hide file tree
Showing 148 changed files with 11,076 additions and 12,079 deletions.
8 changes: 8 additions & 0 deletions components/driver/.build-test-rules.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps

components/driver/test_apps/dac_test_apps/dac:
disable:
- if: SOC_DAC_SUPPORTED != 1

components/driver/test_apps/dac_test_apps/legacy_dac_driver:
disable:
- if: SOC_DAC_SUPPORTED != 1

components/driver/test_apps/i2s_test_apps:
disable:
- if: SOC_I2S_SUPPORTED != 1
Expand Down
20 changes: 12 additions & 8 deletions components/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,26 @@ if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2)
endif()

if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
list(APPEND srcs "touch_sensor_common.c" "${target}/touch_sensor.c")
list(APPEND srcs "touch_sensor_common.c"
"${target}/touch_sensor.c")
endif()

if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED)
list(APPEND srcs "sdio_slave.c")
endif()

if(${target} STREQUAL "esp32")
list(APPEND srcs "dac_common.c"
"deprecated/adc_i2s_deprecated.c"
"esp32/dac.c")
if(CONFIG_SOC_DAC_SUPPORTED)
list(APPEND srcs "dac/dac_oneshot.c"
"dac/dac_cosine.c"
"dac/dac_conti.c"
"dac/dac_common.c"
"dac/${target}/dac_dma.c"
"deprecated/dac_common_legacy.c"
"deprecated/${target}/dac_legacy.c")
endif()

if(${target} STREQUAL "esp32s2")
list(APPEND srcs "dac_common.c"
"esp32s2/dac.c")
if(${target} STREQUAL "esp32")
list(APPEND srcs "deprecated/adc_i2s_deprecated.c")
endif()

if(BOOTLOADER_BUILD)
Expand Down
46 changes: 46 additions & 0 deletions components/driver/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,50 @@ menu "Driver Configurations"
Note that, this option only controls the I2S driver log, will not affect other drivers.
endmenu # I2S Configuration

menu "DAC Configuration"
depends on SOC_DAC_SUPPORTED
config DAC_CTRL_FUNC_IN_IRAM
bool "Place DAC control functions into IRAM"
default n
help
Place DAC control functions (e.g. 'dac_oneshot_output_voltage') into IRAM,
so that this function can be IRAM-safe and able to be called in the other IRAM interrupt context.
Enabling this option can improve driver performance as well.

config DAC_ISR_IRAM_SAFE
bool "DAC ISR IRAM-Safe"
default n
help
Ensure the DAC interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).

config DAC_SUPPRESS_DEPRECATE_WARN
bool "Suppress legacy driver deprecated warning"
default n
help
Wether 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_ENABLE_DEBUG_LOG
bool "Enable debug log"
default n
help
Wether to enable the debug log message for DAC driver.
Note that, this option only controls the DAC driver log, won't affect other drivers.

config DAC_DMA_AUTO_16BIT_ALIGN
bool "Align the continuous data to 16 bit automatically"
depends on SOC_DAC_DMA_16BIT_ALIGN
default y
help
Whether to left shift the continuous data to align every bytes to 16 bits in the driver.
On ESP32, although the DAC resolution is only 8 bits,
the hardware requires 16 bits data in continuous mode.
By enabling this option, the driver will left shift 8 bits for the input data automatically.
Only disable this option when you decide to do this step by yourself.
Note that the driver will allocate a new piece of memory to save the converted data.

endmenu # DAC Configuration

endmenu # Driver configurations
98 changes: 98 additions & 0 deletions components/driver/dac/dac_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdint.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "soc/soc_caps.h"
#include "soc/dac_periph.h"
#include "hal/dac_types.h"
#include "hal/dac_ll.h"
#include "driver/rtc_io.h"
#include "esp_check.h"
#include "dac_priv_common.h"

typedef struct {
bool in_use;
bool is_enabled;
const char *mode;
} dac_channel_info_t;

static dac_channel_info_t s_dac_chan[SOC_DAC_CHAN_NUM] = {
[0 ... SOC_DAC_CHAN_NUM - 1] = {
.in_use = false,
.is_enabled = false,
.mode = NULL,
}
};
/* Global dac spin lock for the whole DAC driver */
portMUX_TYPE dac_spinlock = portMUX_INITIALIZER_UNLOCKED;

static const char *TAG = "dac_common";

esp_err_t dac_priv_register_channel(dac_channel_t chan_id, const char *mode_name)
{
ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
DAC_NULL_POINTER_CHECK(mode_name);
esp_err_t ret = ESP_OK;
if (!s_dac_chan[chan_id].in_use) {
s_dac_chan[chan_id].in_use = true;
s_dac_chan[chan_id].mode = mode_name;
} else {
ret = ESP_ERR_INVALID_STATE;
}
if (ret != ESP_OK) {
ESP_LOGE(TAG, "dac channel %d has been registered by %s", chan_id, s_dac_chan[chan_id].mode);
}
return ret;
}

esp_err_t dac_priv_deregister_channel(dac_channel_t chan_id)
{
ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
ESP_RETURN_ON_FALSE(!s_dac_chan[chan_id].is_enabled, ESP_ERR_INVALID_STATE, TAG, "the channel is still enabled");
esp_err_t ret = ESP_OK;
if (s_dac_chan[chan_id].in_use) {
s_dac_chan[chan_id].in_use = false;
s_dac_chan[chan_id].mode = NULL;
} else {
ret = ESP_ERR_INVALID_STATE;
}
return ret;
}

esp_err_t dac_priv_enable_channel(dac_channel_t chan_id)
{
ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
ESP_RETURN_ON_FALSE(s_dac_chan[chan_id].in_use, ESP_ERR_INVALID_STATE, TAG, "the channel is not registered");

gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id];
rtc_gpio_init(gpio_num);
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
rtc_gpio_pullup_dis(gpio_num);
rtc_gpio_pulldown_dis(gpio_num);
DAC_RTC_ENTER_CRITICAL();
dac_ll_power_on(chan_id);
dac_ll_rtc_sync_by_adc(false);
DAC_RTC_EXIT_CRITICAL();
s_dac_chan[chan_id].is_enabled = true;
return ESP_OK;
}

esp_err_t dac_priv_disable_channel(dac_channel_t chan_id)
{
ESP_RETURN_ON_FALSE(chan_id < SOC_DAC_CHAN_NUM, ESP_ERR_INVALID_ARG, TAG, "channel id is invalid");
ESP_RETURN_ON_FALSE(s_dac_chan[chan_id].in_use, ESP_ERR_INVALID_STATE, TAG, "the channel is not registered");

gpio_num_t gpio_num = (gpio_num_t)dac_periph_signal.dac_channel_io_num[chan_id];
rtc_gpio_deinit(gpio_num);
DAC_RTC_ENTER_CRITICAL();
dac_ll_power_down(chan_id);
DAC_RTC_EXIT_CRITICAL();
s_dac_chan[chan_id].is_enabled = false;

return ESP_OK;
}
Loading

0 comments on commit 9bc2d15

Please sign in to comment.