mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
dfiver(dac): add dac dma driver and unit test
This commit is contained in:
parent
cf3be75844
commit
0914dfbb6a
@ -1,6 +1,6 @@
|
||||
set(srcs
|
||||
"adc_common.c"
|
||||
"dac.c"
|
||||
"dac_common.c"
|
||||
"gpio.c"
|
||||
"i2c.c"
|
||||
"i2s.c"
|
||||
@ -32,7 +32,8 @@ if(IDF_TARGET STREQUAL "esp32")
|
||||
"sdmmc_host.c"
|
||||
"sdmmc_transaction.c"
|
||||
"esp32/touch_sensor.c"
|
||||
"esp32/adc.c")
|
||||
"esp32/adc.c"
|
||||
"esp32/dac.c")
|
||||
list(APPEND includes "esp32/include")
|
||||
endif()
|
||||
|
||||
@ -42,7 +43,7 @@ if(IDF_TARGET STREQUAL "esp32s2")
|
||||
"esp32s2/adc.c"
|
||||
"esp32s2/adc2_init_cal.c"
|
||||
"spi_slave_hd.c"
|
||||
)
|
||||
"esp32s2/dac.c")
|
||||
# currently only S2 beta has its own target-specific includes
|
||||
list(APPEND includes "esp32s2/include")
|
||||
endif()
|
||||
|
@ -107,24 +107,6 @@ esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_i2s_enable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
dac_hal_dma_enable();
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_i2s_disable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
dac_hal_dma_disable();
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_cw_generator_enable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
@ -145,7 +127,7 @@ esp_err_t dac_cw_generator_disable(void)
|
||||
|
||||
esp_err_t dac_cw_generator_config(dac_cw_config_t *cw)
|
||||
{
|
||||
assert(cw != NULL);
|
||||
if (!cw) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
dac_hal_cw_generator_config(cw);
|
51
components/driver/esp32/dac.c
Normal file
51
components/driver/esp32/dac.c
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/dac.h"
|
||||
#include "soc/dac_periph.h"
|
||||
#include "hal/dac_hal.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_hal_digi_enable_dma(true);
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_i2s_disable(void)
|
||||
{
|
||||
DAC_ENTER_CRITICAL();
|
||||
dac_hal_digi_enable_dma(false);
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
44
components/driver/esp32/include/driver/dac.h
Normal file
44
components/driver/esp32/include/driver/dac.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/dac_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/rtc_io.h"
|
||||
@ -56,6 +57,10 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
|
||||
#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
|
||||
#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
static esp_pm_lock_handle_t s_adc_digi_arbiter_lock = NULL;
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
@ -71,6 +76,12 @@ esp_err_t adc_digi_init(void)
|
||||
|
||||
esp_err_t adc_digi_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_adc_digi_arbiter_lock) {
|
||||
esp_pm_lock_delete(s_adc_digi_arbiter_lock);
|
||||
s_adc_digi_arbiter_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_init();
|
||||
ADC_EXIT_CRITICAL();
|
||||
@ -79,6 +90,22 @@ esp_err_t adc_digi_deinit(void)
|
||||
|
||||
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_err_t err;
|
||||
if (s_adc_digi_arbiter_lock == NULL) {
|
||||
if (config->dig_clk.use_apll) {
|
||||
err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "adc_dma", &s_adc_digi_arbiter_lock);
|
||||
} else {
|
||||
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_arbiter_lock);
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
s_adc_digi_arbiter_lock = NULL;
|
||||
ESP_LOGE(ADC_TAG, "ADC-DMA pm lock error");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_controller_config(config);
|
||||
ADC_EXIT_CRITICAL();
|
||||
@ -157,6 +184,10 @@ esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
|
||||
|
||||
esp_err_t adc_digi_start(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
ADC_CHECK((s_adc_digi_arbiter_lock), "Should start after call `adc_digi_controller_config`", ESP_FAIL);
|
||||
esp_pm_lock_acquire(s_adc_digi_arbiter_lock);
|
||||
#endif
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_enable();
|
||||
ADC_EXIT_CRITICAL();
|
||||
@ -165,6 +196,11 @@ esp_err_t adc_digi_start(void)
|
||||
|
||||
esp_err_t adc_digi_stop(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_adc_digi_arbiter_lock) {
|
||||
esp_pm_lock_release(s_adc_digi_arbiter_lock);
|
||||
}
|
||||
#endif
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_disable();
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
146
components/driver/esp32s2/dac.c
Normal file
146
components/driver/esp32s2/dac.c
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_pm.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/dac.h"
|
||||
#include "soc/dac_periph.h"
|
||||
#include "hal/dac_hal.h"
|
||||
|
||||
static const char *DAC_TAG = "DAC";
|
||||
|
||||
#define DAC_CHECK(a, str, ret_val) ({ \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(DAC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
} \
|
||||
})
|
||||
|
||||
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_hal_digi_init();
|
||||
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_hal_digi_deinit();
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg)
|
||||
{
|
||||
DAC_CHECK(cfg->mode < DAC_CONV_MAX, "DAC mode error", ESP_ERR_INVALID_ARG);
|
||||
DAC_CHECK(cfg->interval > 0 && cfg->interval < 4096, "DAC interval error", ESP_ERR_INVALID_ARG);
|
||||
DAC_CHECK(cfg->dig_clk.div_num < 256, "DAC clk div_num error", ESP_ERR_INVALID_ARG);
|
||||
DAC_CHECK(cfg->dig_clk.div_b > 0 && cfg->dig_clk.div_b < 64, "DAC clk div_b error", ESP_ERR_INVALID_ARG);
|
||||
DAC_CHECK(cfg->dig_clk.div_a < 64, "DAC clk div_a error", ESP_ERR_INVALID_ARG);
|
||||
#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(DAC_TAG, "DAC-DMA pm lock error");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
|
||||
DAC_ENTER_CRITICAL();
|
||||
dac_hal_digi_controller_config(cfg);
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_digi_start(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
DAC_CHECK((s_dac_digi_lock), "Should start after call `dac_digi_controller_config`", ESP_FAIL);
|
||||
esp_pm_lock_acquire(s_dac_digi_lock);
|
||||
#endif
|
||||
DAC_ENTER_CRITICAL();
|
||||
dac_hal_digi_start();
|
||||
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_hal_digi_stop();
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_digi_fifo_reset(void)
|
||||
{
|
||||
DAC_ENTER_CRITICAL();
|
||||
dac_hal_digi_fifo_reset();
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t dac_digi_reset(void)
|
||||
{
|
||||
DAC_ENTER_CRITICAL();
|
||||
dac_hal_digi_reset();
|
||||
DAC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
80
components/driver/esp32s2/include/driver/dac.h
Normal file
80
components/driver/esp32s2/include/driver/dac.h
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/dac_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @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 paramter. 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -67,22 +67,6 @@ esp_err_t dac_output_enable(dac_channel_t channel);
|
||||
*/
|
||||
esp_err_t dac_output_disable(dac_channel_t channel);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Enable cosine wave generator output.
|
||||
*
|
||||
@ -105,6 +89,7 @@ esp_err_t dac_cw_generator_disable(void);
|
||||
* @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);
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/adc_periph.h"
|
||||
#include "test/test_common_adc.h"
|
||||
#include "esp_rom_sys.h"
|
||||
@ -41,6 +40,7 @@
|
||||
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "test/test_adc_dac_dma.h"
|
||||
|
||||
static const char *TAG = "test_adc";
|
||||
|
||||
@ -88,9 +88,6 @@ static adc_channel_t adc_list[SOC_ADC_PATT_LEN_MAX] = {
|
||||
/* For ESP32S2, it should use same atten, or, it will have error. */
|
||||
#define TEST_ADC_ATTEN_DEFAULT (ADC_ATTEN_11db)
|
||||
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE */
|
||||
/*******************************************/
|
||||
extern esp_err_t adc_digi_reset(void);
|
||||
|
||||
/* Work mode.
|
||||
@ -100,7 +97,7 @@ extern esp_err_t adc_digi_reset(void);
|
||||
* */
|
||||
#define SAR_SIMPLE_NUM 512 // Set sample number of enabled unit.
|
||||
/* Use two DMA linker to save ADC data. ADC sample 1 times -> 2 byte data -> 2 DMA link buf. */
|
||||
#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num)) //
|
||||
#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num))
|
||||
#define SAR_EOF_NUMBER(unit, sample_num) ((sample_num) * (unit))
|
||||
#define SAR_MEAS_LIMIT_NUM(unit, sample_num) (SAR_SIMPLE_NUM)
|
||||
#define SAR_SIMPLE_TIMEOUT_MS 1000
|
||||
@ -114,7 +111,6 @@ typedef struct dma_msg {
|
||||
static uint8_t link_buf[2][SAR_DMA_DATA_SIZE(2, SAR_SIMPLE_NUM)] = {0};
|
||||
static lldesc_t dma1 = {0};
|
||||
static lldesc_t dma2 = {0};
|
||||
static bool adc_dma_flag = false;
|
||||
static QueueHandle_t que_adc = NULL;
|
||||
static adc_dma_event_t adc_evt;
|
||||
|
||||
@ -138,34 +134,13 @@ static IRAM_ATTR void adc_dma_isr(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** Register ADC-DMA handler. */
|
||||
static esp_err_t adc_dma_isr_register(void (*fun)(void *), void *arg)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
ret = esp_intr_alloc(ETS_SPI3_DMA_INTR_SOURCE, 0, fun, arg, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Reset DMA linker pointer and start DMA. */
|
||||
static void dma_linker_restart(void)
|
||||
{
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
SET_PERI_REG_BITS(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_ADDR, (uint32_t)&dma1, 0);
|
||||
REG_SET_BIT(SPI_DMA_CONF_REG(3), SPI_IN_RST);
|
||||
REG_CLR_BIT(SPI_DMA_CONF_REG(3), SPI_IN_RST);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* DMA liner initialization and start.
|
||||
* @param is_loop
|
||||
* - true: The two dma linked lists are connected end to end, with no end mark (eof).
|
||||
* - false: The two dma linked lists are connected end to end, with end mark (eof).
|
||||
* @param int_mask DMA interrupt types.
|
||||
*/
|
||||
static void dma_linker_init(adc_unit_t adc, bool is_loop, uint32_t int_mask)
|
||||
static uint32_t adc_dma_linker_init(adc_unit_t adc, bool is_loop)
|
||||
{
|
||||
dma1 = (lldesc_t) {
|
||||
.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM),
|
||||
@ -183,26 +158,9 @@ static void dma_linker_init(adc_unit_t adc, bool is_loop, uint32_t int_mask)
|
||||
} else {
|
||||
dma2.qe.stqe_next = NULL;
|
||||
}
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_APB_SARADC_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_DMA_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_DMA_RST_M);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST_M);
|
||||
if (!adc_dma_flag) {
|
||||
que_adc = xQueueCreate(5, sizeof(adc_dma_event_t));
|
||||
adc_dma_isr_register(adc_dma_isr, NULL);
|
||||
adc_dma_flag = true;
|
||||
}
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), 0xFFFFFFFF);
|
||||
REG_WRITE(SPI_DMA_INT_ENA_REG(3), int_mask);
|
||||
dma_linker_restart();
|
||||
printf("reg addr 0x%08x 0x%08x \n", SPI_DMA_IN_LINK_REG(3), (uint32_t)&dma1);
|
||||
return (uint32_t)&dma1;
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE END */
|
||||
/*******************************************/
|
||||
|
||||
#define DEBUG_CHECK_ENABLE 1
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#define DEBUG_CHECK_ERROR 10
|
||||
@ -285,7 +243,7 @@ static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc, void *dma_addr, uint32_t int_mask)
|
||||
{
|
||||
adc_dma_event_t evt;
|
||||
|
||||
@ -301,7 +259,7 @@ static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
}
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
adc_digi_reset();
|
||||
TEST_ESP_OK( adc_dma_data_check(adc, -1) ); // Don't check data.
|
||||
|
||||
@ -317,7 +275,7 @@ static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
}
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
adc_digi_reset();
|
||||
TEST_ESP_OK( adc_dma_data_check(adc, 1) );
|
||||
|
||||
@ -333,7 +291,7 @@ static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
}
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
adc_digi_reset();
|
||||
TEST_ESP_OK( adc_dma_data_check(adc, 0) );
|
||||
|
||||
@ -349,7 +307,7 @@ static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
}
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
adc_digi_reset();
|
||||
TEST_ESP_OK( adc_dma_data_check(adc, 2) );
|
||||
|
||||
@ -469,11 +427,22 @@ int test_adc_dig_dma_single_unit(adc_unit_t adc)
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_controller_config(&config) );
|
||||
|
||||
dma_linker_init(adc, false, SPI_IN_SUC_EOF_INT_ENA);
|
||||
/* ADC-DMA linker init */
|
||||
if (que_adc == NULL) {
|
||||
que_adc = xQueueCreate(5, sizeof(adc_dma_event_t));
|
||||
} else {
|
||||
xQueueReset(que_adc);
|
||||
}
|
||||
uint32_t int_mask = SPI_IN_SUC_EOF_INT_ENA;
|
||||
uint32_t dma_addr = adc_dma_linker_init(adc, false);
|
||||
adc_dac_dma_isr_register(adc_dma_isr, NULL, int_mask);
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
|
||||
TEST_ESP_OK( adc_check_patt_table(adc, adc_test_num, adc_list[adc_test_num - 1]) );
|
||||
adc_dma_data_multi_st_check(adc);
|
||||
|
||||
adc_dma_data_multi_st_check(adc, (void *)dma_addr, int_mask);
|
||||
|
||||
adc_dac_dma_linker_deinit();
|
||||
adc_dac_dma_isr_deregister(adc_dma_isr, NULL);
|
||||
TEST_ESP_OK( adc_digi_deinit() );
|
||||
return 0;
|
||||
}
|
||||
@ -565,7 +534,16 @@ int test_adc_dig_scope_debug_unit(adc_unit_t adc)
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_controller_config(&config) );
|
||||
|
||||
dma_linker_init(adc, false, SPI_IN_DONE_INT_ENA & SPI_IN_SUC_EOF_INT_ENA);
|
||||
/* ADC-DMA linker init */
|
||||
if (que_adc == NULL) {
|
||||
que_adc = xQueueCreate(5, sizeof(adc_dma_event_t));
|
||||
} else {
|
||||
xQueueReset(que_adc);
|
||||
}
|
||||
uint32_t int_mask = SPI_IN_SUC_EOF_INT_ENA;
|
||||
uint32_t dma_addr = adc_dma_linker_init(adc, false);
|
||||
adc_dac_dma_isr_register(adc_dma_isr, NULL, int_mask);
|
||||
adc_dac_dma_linker_start(DMA_ONLY_ADC_INLINK, (void *)dma_addr, int_mask);
|
||||
|
||||
ESP_LOGI(TAG, "adc IO fake tie middle, test ...");
|
||||
for (int i = 0; i < adc_test_num; i++) {
|
||||
@ -630,7 +608,6 @@ TEST_CASE("test_adc_digi_slope_debug", "[adc_dma][ignore]")
|
||||
TEST_ASSERT_EQUAL( xQueueReceive(que_adc, &evt, portMAX_DELAY), pdTRUE );
|
||||
if (evt.int_msk & SPI_IN_SUC_EOF_INT_ST) {
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
adc_digi_reset();
|
||||
for (int cnt = 0; cnt < 2; cnt++) {
|
||||
esp_rom_printf("cnt%d\n", cnt);
|
||||
|
365
components/driver/test/dac_dma_test/test_esp32s2.c
Normal file
365
components/driver/test/dac_dma_test/test_esp32s2.c
Normal file
@ -0,0 +1,365 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Tests for the dac device driver
|
||||
*/
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/adc_periph.h"
|
||||
#include "soc/dac_periph.h"
|
||||
#include "test/test_common_adc.h"
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP8266, ESP32) // This testcase for ESP32S2
|
||||
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp32s2/rom/lldesc.h"
|
||||
#include "test/test_adc_dac_dma.h"
|
||||
|
||||
static const char *TAG = "test_adc";
|
||||
|
||||
#define PLATFORM_SELECT (1) //0: pxp; 1: chip
|
||||
#if (PLATFORM_SELECT == 0) //PXP platform
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag)
|
||||
//PXP clk is slower.
|
||||
#define SYS_DELAY_TIME_MOM (1/40)
|
||||
#define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz.
|
||||
static void test_pxp_deinit_io(void)
|
||||
{
|
||||
for (int i = 0; i < 22; i++) {
|
||||
rtc_gpio_init(i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
//PXP clk is slower.
|
||||
#define SET_BREAK_POINT(flag)
|
||||
#define SYS_DELAY_TIME_MOM (1)
|
||||
#define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz.
|
||||
#endif
|
||||
|
||||
#define SAR_SIMPLE_NUM 512 // Set out number of enabled unit.
|
||||
|
||||
typedef struct dma_msg {
|
||||
uint32_t int_msk;
|
||||
uint8_t *data;
|
||||
uint32_t data_len;
|
||||
} dac_dma_event_t;
|
||||
|
||||
static QueueHandle_t que_dac = NULL;
|
||||
static uint8_t link_buf[2][SAR_SIMPLE_NUM*2] = {0};
|
||||
static lldesc_t dma1 = {0};
|
||||
static lldesc_t dma2 = {0};
|
||||
|
||||
/*******************************************/
|
||||
/** DAC-DMA INIT CODE */
|
||||
/*******************************************/
|
||||
|
||||
/**
|
||||
* DMA liner initialization and start.
|
||||
* @param is_loop
|
||||
* - true: The two dma linked lists are connected end to end, with no end mark (eof).
|
||||
* - false: The two dma linked lists are connected end to end, with end mark (eof).
|
||||
* @param int_mask DMA interrupt types.
|
||||
*/
|
||||
uint32_t dac_dma_linker_init(bool is_alter, bool is_loop)
|
||||
{
|
||||
/* The DAC output is a sawtooth wave. */
|
||||
if (is_alter) {
|
||||
for(int i=0; i<SAR_SIMPLE_NUM*2; i++) {
|
||||
if(i%2){
|
||||
link_buf[0][i] = i%256;
|
||||
}else{
|
||||
link_buf[0][i] = 256-i%256;
|
||||
}
|
||||
if(i%2){
|
||||
link_buf[1][i] = i%256;
|
||||
}else{
|
||||
link_buf[1][i] = 256-i%256;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int i=0; i<SAR_SIMPLE_NUM; i++) {
|
||||
link_buf[0][i] = i%256;
|
||||
link_buf[1][i] = i%256;
|
||||
}
|
||||
}
|
||||
dma1 = (lldesc_t) {
|
||||
.size = (is_alter) ? SAR_SIMPLE_NUM*2 : SAR_SIMPLE_NUM,
|
||||
.length = (is_alter) ? SAR_SIMPLE_NUM*2 : SAR_SIMPLE_NUM,
|
||||
.eof = 0,
|
||||
.owner = 1,
|
||||
.buf = &link_buf[0][0],
|
||||
.qe.stqe_next = &dma2,
|
||||
};
|
||||
dma2 = (lldesc_t) {
|
||||
.size = (is_alter) ? SAR_SIMPLE_NUM*2 : SAR_SIMPLE_NUM,
|
||||
.length = (is_alter) ? SAR_SIMPLE_NUM*2 : SAR_SIMPLE_NUM,
|
||||
.owner = 1,
|
||||
.buf = &link_buf[1][0],
|
||||
};
|
||||
if (is_loop) {
|
||||
dma2.eof = 0;
|
||||
dma2.qe.stqe_next = &dma1;
|
||||
} else {
|
||||
dma2.eof = 1;
|
||||
dma2.qe.stqe_next = NULL;
|
||||
}
|
||||
return (uint32_t)&dma1;
|
||||
}
|
||||
|
||||
/** ADC-DMA ISR handler. */
|
||||
static IRAM_ATTR void dac_dma_isr(void * arg)
|
||||
{
|
||||
uint32_t int_st = REG_READ(SPI_DMA_INT_ST_REG(3));
|
||||
int task_awoken = pdFALSE;
|
||||
dac_dma_event_t adc_evt;
|
||||
adc_evt.int_msk = int_st;
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), int_st);
|
||||
xQueueSendFromISR(que_dac, &adc_evt, &task_awoken);
|
||||
ESP_EARLY_LOGV(TAG, "int msk%x, raw%x", int_st, REG_READ(SPI_DMA_INT_RAW_REG(3)));
|
||||
|
||||
if (task_awoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase: Check the interrupt types of DAC-DMA.
|
||||
*/
|
||||
void test_dac_dig_dma_intr_check(dac_digi_convert_mode_t mode)
|
||||
{
|
||||
ESP_LOGI(TAG, " >> %s - dac mode %d<< ", __func__, mode);
|
||||
|
||||
dac_dma_event_t evt;
|
||||
|
||||
dac_digi_init();
|
||||
const dac_digi_config_t cfg = {
|
||||
.mode = mode,
|
||||
.interval = 100,
|
||||
.dig_clk.use_apll = false, // APB clk
|
||||
.dig_clk.div_num = 79,
|
||||
.dig_clk.div_b = 1,
|
||||
.dig_clk.div_a = 0,
|
||||
};
|
||||
dac_digi_controller_config(&cfg);
|
||||
dac_output_enable(DAC_CHANNEL_1);
|
||||
dac_output_enable(DAC_CHANNEL_2);
|
||||
|
||||
/* DAC-DMA linker init */
|
||||
if (que_dac == NULL) {
|
||||
que_dac = xQueueCreate(5, sizeof(dac_dma_event_t));
|
||||
} else {
|
||||
xQueueReset(que_dac);
|
||||
}
|
||||
uint32_t int_mask = SPI_OUT_DONE_INT_ENA | SPI_OUT_EOF_INT_ENA | SPI_OUT_TOTAL_EOF_INT_ENA;
|
||||
uint32_t dma_addr = dac_dma_linker_init(mode, false);
|
||||
adc_dac_dma_isr_register(dac_dma_isr, NULL, int_mask);
|
||||
adc_dac_dma_linker_start(DMA_ONLY_DAC_OUTLINK, (void *)dma_addr, int_mask);
|
||||
|
||||
/* ADC-DMA start output */
|
||||
dac_digi_start();
|
||||
|
||||
/* Check interrupt type */
|
||||
while (int_mask) {
|
||||
TEST_ASSERT_EQUAL( xQueueReceive(que_dac, &evt, 2000 / portTICK_RATE_MS), pdTRUE );
|
||||
ESP_LOGI(TAG, "DAC-DMA intr type 0x%x", evt.int_msk);
|
||||
if (evt.int_msk & int_mask) {
|
||||
int_mask &= (~evt.int_msk);
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "DAC-DMA intr test over");
|
||||
adc_dac_dma_linker_deinit();
|
||||
adc_dac_dma_isr_deregister(dac_dma_isr, NULL);
|
||||
TEST_ESP_OK( dac_digi_deinit() );
|
||||
}
|
||||
|
||||
TEST_CASE("DAC-DMA interrupt test", "[dac]")
|
||||
{
|
||||
test_dac_dig_dma_intr_check(DAC_CONV_NORMAL);
|
||||
test_dac_dig_dma_intr_check(DAC_CONV_ALTER);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE */
|
||||
/*******************************************/
|
||||
|
||||
#include "sys/queue.h"
|
||||
static bool adc_dac_dma_isr_flag = false;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTERRUPT HANDLER
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
typedef struct adc_dac_dma_isr_handler_ {
|
||||
uint32_t mask;
|
||||
intr_handler_t handler;
|
||||
void* handler_arg;
|
||||
SLIST_ENTRY(adc_dac_dma_isr_handler_) next;
|
||||
} adc_dac_dma_isr_handler_t;
|
||||
|
||||
static SLIST_HEAD(adc_dac_dma_isr_handler_list_, adc_dac_dma_isr_handler_) s_adc_dac_dma_isr_handler_list =
|
||||
SLIST_HEAD_INITIALIZER(s_adc_dac_dma_isr_handler_list);
|
||||
portMUX_TYPE s_isr_handler_list_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
static intr_handle_t s_adc_dac_dma_isr_handle;
|
||||
|
||||
static IRAM_ATTR void adc_dac_dma_isr_default(void* arg)
|
||||
{
|
||||
uint32_t status = REG_READ(SPI_DMA_INT_ST_REG(3));
|
||||
adc_dac_dma_isr_handler_t* it;
|
||||
portENTER_CRITICAL_ISR(&s_isr_handler_list_lock);
|
||||
SLIST_FOREACH(it, &s_adc_dac_dma_isr_handler_list, next) {
|
||||
if (it->mask & status) {
|
||||
portEXIT_CRITICAL_ISR(&s_isr_handler_list_lock);
|
||||
(*it->handler)(it->handler_arg);
|
||||
portENTER_CRITICAL_ISR(&s_isr_handler_list_lock);
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&s_isr_handler_list_lock);
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), status);
|
||||
}
|
||||
|
||||
static esp_err_t adc_dac_dma_isr_ensure_installed(void)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
portENTER_CRITICAL(&s_isr_handler_list_lock);
|
||||
if (s_adc_dac_dma_isr_handle) {
|
||||
goto out;
|
||||
}
|
||||
REG_WRITE(SPI_DMA_INT_ENA_REG(3), 0);
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), UINT32_MAX);
|
||||
err = esp_intr_alloc(ETS_SPI3_DMA_INTR_SOURCE, 0, &adc_dac_dma_isr_default, NULL, &s_adc_dac_dma_isr_handle);
|
||||
if (err != ESP_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
portEXIT_CRITICAL(&s_isr_handler_list_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t adc_dac_dma_isr_register(intr_handler_t handler, void* handler_arg, uint32_t intr_mask)
|
||||
{
|
||||
esp_err_t err = adc_dac_dma_isr_ensure_installed();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
adc_dac_dma_isr_handler_t* item = malloc(sizeof(*item));
|
||||
if (item == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
item->handler = handler;
|
||||
item->handler_arg = handler_arg;
|
||||
item->mask = intr_mask;
|
||||
portENTER_CRITICAL(&s_isr_handler_list_lock);
|
||||
SLIST_INSERT_HEAD(&s_adc_dac_dma_isr_handler_list, item, next);
|
||||
portEXIT_CRITICAL(&s_isr_handler_list_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_dac_dma_isr_deregister(intr_handler_t handler, void* handler_arg)
|
||||
{
|
||||
adc_dac_dma_isr_handler_t* it;
|
||||
adc_dac_dma_isr_handler_t* prev = NULL;
|
||||
bool found = false;
|
||||
portENTER_CRITICAL(&s_isr_handler_list_lock);
|
||||
SLIST_FOREACH(it, &s_adc_dac_dma_isr_handler_list, next) {
|
||||
if (it->handler == handler && it->handler_arg == handler_arg) {
|
||||
if (it == SLIST_FIRST(&s_adc_dac_dma_isr_handler_list)) {
|
||||
SLIST_REMOVE_HEAD(&s_adc_dac_dma_isr_handler_list, next);
|
||||
} else {
|
||||
SLIST_REMOVE_AFTER(prev, next);
|
||||
}
|
||||
found = true;
|
||||
free(it);
|
||||
break;
|
||||
}
|
||||
prev = it;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_isr_handler_list_lock);
|
||||
return found ? ESP_OK : ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
void adc_dac_dma_linker_start(spi_dma_link_type_t type, void *dma_addr, uint32_t int_msk)
|
||||
{
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_APB_SARADC_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_DMA_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_DMA_RST_M);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST_M);
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), 0xFFFFFFFF);
|
||||
REG_WRITE(SPI_DMA_INT_ENA_REG(3), int_msk | REG_READ(SPI_DMA_INT_ENA_REG(3)));
|
||||
if (type & DMA_ONLY_ADC_INLINK) {
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
SET_PERI_REG_BITS(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_ADDR, (uint32_t)dma_addr, 0);
|
||||
REG_SET_BIT(SPI_DMA_CONF_REG(3), SPI_IN_RST);
|
||||
REG_CLR_BIT(SPI_DMA_CONF_REG(3), SPI_IN_RST);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
}
|
||||
if (type & DMA_ONLY_DAC_OUTLINK) {
|
||||
REG_SET_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_START);
|
||||
SET_PERI_REG_BITS(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_ADDR, (uint32_t)dma_addr, 0);
|
||||
REG_SET_BIT(SPI_DMA_CONF_REG(3), SPI_OUT_RST);
|
||||
REG_CLR_BIT(SPI_DMA_CONF_REG(3), SPI_OUT_RST);
|
||||
REG_CLR_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_STOP);
|
||||
REG_SET_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_START);
|
||||
}
|
||||
}
|
||||
|
||||
void adc_dac_dma_linker_stop(spi_dma_link_type_t type)
|
||||
{
|
||||
if (type & DMA_ONLY_ADC_INLINK) {
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
}
|
||||
if (type & DMA_ONLY_DAC_OUTLINK) {
|
||||
REG_SET_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_OUT_LINK_REG(3), SPI_OUTLINK_START);
|
||||
}
|
||||
}
|
||||
|
||||
void adc_dac_dma_linker_deinit(void)
|
||||
{
|
||||
adc_dac_dma_linker_stop(DMA_BOTH_ADC_DAC);
|
||||
REG_WRITE(SPI_DMA_INT_CLR_REG(3), 0xFFFFFFFF);
|
||||
REG_WRITE(SPI_DMA_INT_ENA_REG(3), 0);
|
||||
adc_dac_dma_isr_flag = false;
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE END */
|
||||
/*******************************************/
|
||||
|
||||
#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32)
|
67
components/driver/test/include/test/test_adc_dac_dma.h
Normal file
67
components/driver/test/include/test/test_adc_dac_dma.h
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP8266, ESP32) // This testcase for ESP32S2
|
||||
|
||||
/**
|
||||
* SPI DMA type.
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_ONLY_ADC_INLINK = BIT(1), /*!<Select ADC-DMA config. */
|
||||
DMA_ONLY_DAC_OUTLINK = BIT(2), /*!<Select DAC-DMA config. */
|
||||
DMA_BOTH_ADC_DAC, /*!<Select DAC-DMA and ADC-DMA config. */
|
||||
#define DMA_BOTH_ADC_DAC (DMA_ONLY_ADC_INLINK | DMA_ONLY_DAC_OUTLINK)
|
||||
} spi_dma_link_type_t;
|
||||
|
||||
/**
|
||||
* Register SPI-DMA interrupt handler.
|
||||
*
|
||||
* @param handler Handler.
|
||||
* @param handler_arg Handler parameter.
|
||||
* @param intr_mask DMA interrupt type mask.
|
||||
*/
|
||||
esp_err_t adc_dac_dma_isr_register(intr_handler_t handler, void* handler_arg, uint32_t intr_mask);
|
||||
|
||||
/**
|
||||
* Deregister SPI-DMA interrupt handler.
|
||||
*
|
||||
* @param handler Handler.
|
||||
* @param handler_arg Handler parameter.
|
||||
*/
|
||||
esp_err_t adc_dac_dma_isr_deregister(intr_handler_t handler, void* handler_arg);
|
||||
|
||||
/**
|
||||
* Reset DMA linker pointer and start DMA.
|
||||
*
|
||||
* @param type DMA linker type. See ``spi_dma_link_type_t``.
|
||||
* @param dma_addr DMA linker addr.
|
||||
* @param int_msk DMA interrupt type mask.
|
||||
*/
|
||||
void adc_dac_dma_linker_start(spi_dma_link_type_t type, void *dma_addr, uint32_t int_msk);
|
||||
|
||||
/**
|
||||
* Stop DMA.
|
||||
*
|
||||
* @param type DMA linker type. See ``spi_dma_link_type_t``.
|
||||
*/
|
||||
void adc_dac_dma_linker_stop(spi_dma_link_type_t type);
|
||||
|
||||
/**
|
||||
* Deinit SPI3 DMA. Disable interrupt, stop DMA trans.
|
||||
*/
|
||||
void adc_dac_dma_linker_deinit(void);
|
||||
|
||||
#endif
|
@ -31,4 +31,4 @@ void adc_fake_tie_middle(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
@ -131,6 +131,8 @@ typedef struct {
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) clock system setting.
|
||||
* Expression: controller_clk = (`APLL` or `APB`) / (div_num + div_a / div_b + 1).
|
||||
*
|
||||
* @note: The clocks of the DAC digital controller use the ADC digital controller clock divider.
|
||||
*/
|
||||
typedef struct {
|
||||
bool use_apll; /*!<true: use APLL clock; false: use APB clock. */
|
||||
@ -260,14 +262,15 @@ typedef struct {
|
||||
pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
|
||||
uint32_t adc2_pattern_len; /*!<Refer to ``adc1_pattern_len`` */
|
||||
adc_digi_pattern_table_t *adc1_pattern; /*!<Pointer to pattern table for digital controller. The table size defined by `adc1_pattern_len`. */
|
||||
adc_digi_pattern_table_t *adc2_pattern; /*!<Refer to ``adc1_pattern`` */
|
||||
adc_digi_pattern_table_t *adc2_pattern; /*!<Refer to `adc1_pattern` */
|
||||
adc_digi_convert_mode_t conv_mode; /*!<ADC conversion mode for digital controller. See ``adc_digi_convert_mode_t``. */
|
||||
adc_digi_output_format_t format; /*!<ADC output data format for digital controller. See ``adc_digi_output_format_t``. */
|
||||
uint32_t interval; /*!<The number of interval clock cycles for the digital controller to trigger the measurement.
|
||||
The unit is the divided clock. Range: 40 ~ 4095.
|
||||
Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``.
|
||||
Note: The sampling rate of each channel is also related to the conversion mode (See ``adc_digi_convert_mode_t``) and pattern table settings. */
|
||||
adc_digi_clk_t dig_clk; /*!<ADC digital controller clock divider settings. Refer to ``adc_digi_clk_t`` */
|
||||
adc_digi_clk_t dig_clk; /*!<ADC 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. */
|
||||
uint32_t dma_eof_num; /*!<DMA eof num of adc digital controller.
|
||||
If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated in DMA.
|
||||
Note: The converted data in the DMA in link buffer will be multiple of two bytes. */
|
||||
|
@ -75,11 +75,6 @@
|
||||
void dac_hal_cw_generator_config(dac_cw_config_t *cw);
|
||||
|
||||
/**
|
||||
* Enable DAC output data from DMA.
|
||||
* Enable/disable DAC output data from DMA.
|
||||
*/
|
||||
#define dac_hal_dma_enable() dac_ll_dma_enable()
|
||||
|
||||
/**
|
||||
* Disable DAC output data from DMA.
|
||||
*/
|
||||
#define dac_hal_dma_disable() dac_ll_dma_disable()
|
||||
#define dac_hal_digi_enable_dma(enable) dac_ll_digi_enable_dma(enable)
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "soc/dac_caps.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef enum {
|
||||
@ -37,4 +38,30 @@ typedef struct {
|
||||
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;
|
||||
} dac_cw_config_t;
|
||||
|
||||
#ifdef 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 //CONFIG_IDF_TARGET_ESP32S2
|
@ -184,25 +184,15 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
|
||||
/* DAC DMA API's */
|
||||
/************************************/
|
||||
/**
|
||||
* Enable DAC output data from I2S DMA.
|
||||
* Enable/disable DAC output data from I2S DMA.
|
||||
* I2S_CLK connect to DAC_CLK, I2S_DATA_OUT connect to DAC_DATA.
|
||||
*/
|
||||
static inline void dac_ll_dma_enable(void)
|
||||
static inline void dac_ll_digi_enable_dma(bool enable)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 1;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = enable;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable DAC output data from I2S DMA.
|
||||
*/
|
||||
static inline void dac_ll_dma_disable(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 0;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
set(srcs "adc_hal.c"
|
||||
"dac_hal.c"
|
||||
"brownout_hal.c"
|
||||
"cp_dma_hal.c"
|
||||
"rtc_clk.c"
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "hal/adc_hal.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
@ -96,6 +96,9 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||
* Enable clock and select clock source for ADC digital controller.
|
||||
* Expression: controller_clk = (`APLL` or `APB`) / (div_num + div_a / div_b + 1).
|
||||
*
|
||||
* @note ADC and DAC digital controller share the same frequency divider.
|
||||
* Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC.
|
||||
*
|
||||
* @param clk Refer to ``adc_digi_clk_t``.
|
||||
*/
|
||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk)
|
||||
|
55
components/soc/src/esp32s2/dac_hal.c
Normal file
55
components/soc/src/esp32s2/dac_hal.c
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for ADC (esp32s2 specific part)
|
||||
|
||||
#include "hal/dac_hal.h"
|
||||
#include "hal/adc_hal.h"
|
||||
#include "hal/dac_types.h"
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
void dac_hal_digi_init(void)
|
||||
{
|
||||
dac_ll_digi_clk_inv(true);
|
||||
}
|
||||
|
||||
void dac_hal_digi_deinit(void)
|
||||
{
|
||||
dac_ll_digi_trigger_output(false);
|
||||
dac_ll_digi_enable_dma(false);
|
||||
dac_ll_digi_fifo_reset();
|
||||
dac_ll_digi_reset();
|
||||
}
|
||||
|
||||
void dac_hal_digi_controller_config(const dac_digi_config_t *cfg)
|
||||
{
|
||||
dac_ll_digi_set_convert_mode(cfg->mode);
|
||||
dac_ll_digi_set_trigger_interval(cfg->interval);
|
||||
adc_hal_digi_clk_config(&cfg->dig_clk);
|
||||
}
|
||||
|
||||
void dac_hal_digi_start(void)
|
||||
{
|
||||
dac_ll_digi_enable_dma(true);
|
||||
dac_ll_digi_trigger_output(true);
|
||||
}
|
||||
|
||||
void dac_hal_digi_stop(void)
|
||||
{
|
||||
dac_ll_digi_trigger_output(false);
|
||||
dac_ll_digi_enable_dma(false);
|
||||
}
|
@ -83,6 +83,9 @@ void adc_hal_digi_disable(void);
|
||||
* Enable clock and select clock source for ADC digital controller.
|
||||
* Expression: controller_clk = (`APLL` or `APB`) / (div_num + div_a / div_b + 1).
|
||||
*
|
||||
* @note ADC and DAC digital controller share the same frequency divider.
|
||||
* Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC.
|
||||
*
|
||||
* @param clk Refer to ``adc_digi_clk_t``.
|
||||
*/
|
||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk);
|
||||
|
76
components/soc/src/esp32s2/include/hal/dac_hal.h
Normal file
76
components/soc/src/esp32s2/include/hal/dac_hal.h
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The HAL layer for DAC (esp32s2 specific part)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/dac_ll.h"
|
||||
#include "hal/dac_types.h"
|
||||
|
||||
#include_next "hal/dac_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Digital controller initialization.
|
||||
*/
|
||||
void dac_hal_digi_init(void);
|
||||
|
||||
/**
|
||||
* Digital controller deinitialization.
|
||||
*/
|
||||
void dac_hal_digi_deinit(void);
|
||||
|
||||
/**
|
||||
* Setting the DAC digital controller.
|
||||
*
|
||||
* @param cfg Pointer to digital controller paramter.
|
||||
*/
|
||||
void dac_hal_digi_controller_config(const dac_digi_config_t *cfg);
|
||||
|
||||
/**
|
||||
* DAC digital controller start output voltage.
|
||||
*/
|
||||
void dac_hal_digi_start(void);
|
||||
|
||||
/**
|
||||
* DAC digital controller stop output voltage.
|
||||
*/
|
||||
void dac_hal_digi_stop(void);
|
||||
|
||||
/**
|
||||
* Reset DAC digital controller FIFO.
|
||||
*/
|
||||
#define dac_hal_digi_fifo_reset() dac_ll_digi_fifo_reset()
|
||||
|
||||
/**
|
||||
* Reset DAC digital controller.
|
||||
*/
|
||||
#define dac_hal_digi_reset() dac_ll_digi_reset()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -23,15 +23,16 @@
|
||||
#include <stdlib.h>
|
||||
#include "soc/dac_periph.h"
|
||||
#include "hal/dac_types.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
DAC common setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Power on dac module and start output voltage.
|
||||
*
|
||||
@ -59,6 +60,9 @@ static inline void dac_ll_power_down(dac_channel_t channel)
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Output voltage with value (8 bit).
|
||||
*
|
||||
@ -204,23 +208,79 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
|
||||
/************************************/
|
||||
/* DAC DMA API's */
|
||||
/************************************/
|
||||
|
||||
/**
|
||||
* Enable DAC output data from I2S DMA.
|
||||
* I2S_CLK connect to DAC_CLK, I2S_DATA_OUT connect to DAC_DATA.
|
||||
* Enable/disable invert the DAC digital controller clock signal.
|
||||
*
|
||||
* @param enable true or false.
|
||||
*/
|
||||
static inline void dac_ll_dma_enable(void)
|
||||
static inline void dac_ll_digi_clk_inv(bool enable)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 1;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable DAC output data from I2S DMA.
|
||||
* Enable/disable DAC-DMA mode for dac digital controller.
|
||||
*/
|
||||
static inline void dac_ll_dma_disable(void)
|
||||
static inline void dac_ll_digi_enable_dma(bool enable)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 0;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = enable;
|
||||
APB_SARADC.apb_dac_ctrl.apb_dac_trans = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of interval clock cycles for the digital controller to trigger the DAC output.
|
||||
* Expression: `dac_output_freq` = `controller_clk` / interval.
|
||||
*
|
||||
* @note The clocks of the DAC digital controller use the ADC digital controller clock divider.
|
||||
*
|
||||
* @param cycle The number of clock cycles for the trigger output interval. The unit is the divided clock.
|
||||
*/
|
||||
static inline void dac_ll_digi_set_trigger_interval(uint32_t cycle)
|
||||
{
|
||||
APB_SARADC.apb_dac_ctrl.dac_timer_target = cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable DAC digital controller to trigger the DAC output.
|
||||
*
|
||||
* @param enable true or false.
|
||||
*/
|
||||
static inline void dac_ll_digi_trigger_output(bool enable)
|
||||
{
|
||||
APB_SARADC.apb_dac_ctrl.dac_timer_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DAC conversion mode for digital controller.
|
||||
*
|
||||
* @param mode Conversion mode select. See ``dac_digi_convert_mode_t``.
|
||||
*/
|
||||
static inline void dac_ll_digi_set_convert_mode(dac_digi_convert_mode_t mode)
|
||||
{
|
||||
if (mode == DAC_CONV_NORMAL) {
|
||||
APB_SARADC.apb_dac_ctrl.apb_dac_alter_mode = 0;
|
||||
} else {
|
||||
APB_SARADC.apb_dac_ctrl.apb_dac_alter_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset FIFO of DAC digital controller.
|
||||
*/
|
||||
static inline void dac_ll_digi_fifo_reset(void)
|
||||
{
|
||||
APB_SARADC.apb_dac_ctrl.dac_reset_fifo = 1;
|
||||
APB_SARADC.apb_dac_ctrl.dac_reset_fifo = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset DAC digital controller.
|
||||
*/
|
||||
static inline void dac_ll_digi_reset(void)
|
||||
{
|
||||
APB_SARADC.apb_dac_ctrl.apb_dac_rst = 1;
|
||||
APB_SARADC.apb_dac_ctrl.apb_dac_rst = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -86,7 +86,6 @@ INPUT = \
|
||||
##
|
||||
## Peripherals - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/driver/include/driver/dac.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/gpio.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/rtc_io.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/i2c.h \
|
||||
@ -102,12 +101,14 @@ INPUT = \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_slave.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_slave_hd.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/adc.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/dac.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
|
||||
$(IDF_PATH)/components/driver/esp32s2/include/driver/temp_sensor.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/timer.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/touch_sensor_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/twai.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/adc_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/dac_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/uart.h \
|
||||
$(IDF_PATH)/components/esp_adc_cal/include/esp_adc_cal.h \
|
||||
$(IDF_PATH)/components/esp32s2/include/cp_dma.h \
|
||||
|
@ -34,6 +34,7 @@ API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/dac.inc
|
||||
.. include-build-file:: inc/dac_common.inc
|
||||
|
||||
GPIO Lookup Macros
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user