1 /*
2 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #include <string.h>
9 #include "sdkconfig.h"
10 #include "freertos/FreeRTOS.h"
11 #include "driver/dac_types_legacy.h"
12 #include "hal/adc_ll.h"
13 #include "hal/dac_ll.h"
14 #include "esp_check.h"
15 #include "esp_pm.h"
16
17 static __attribute__((unused)) const char *TAG = "DAC";
18
19 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
20 #define DAC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
21 #define DAC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
22
23 #ifdef CONFIG_PM_ENABLE
24 static esp_pm_lock_handle_t s_dac_digi_lock = NULL;
25 #endif //CONFIG_PM_ENABLE
26
27 /*---------------------------------------------------------------
28 Digital controller setting
29 ---------------------------------------------------------------*/
30
dac_digi_init(void)31 esp_err_t dac_digi_init(void)
32 {
33 DAC_ENTER_CRITICAL();
34 dac_ll_digi_clk_inv(true);
35 DAC_EXIT_CRITICAL();
36
37 return ESP_OK;
38 }
39
dac_digi_deinit(void)40 esp_err_t dac_digi_deinit(void)
41 {
42 #ifdef CONFIG_PM_ENABLE
43 if (s_dac_digi_lock) {
44 esp_pm_lock_delete(s_dac_digi_lock);
45 s_dac_digi_lock = NULL;
46 }
47 #endif
48 DAC_ENTER_CRITICAL();
49 dac_ll_digi_trigger_output(false);
50 dac_ll_digi_enable_dma(false);
51 dac_ll_digi_fifo_reset();
52 dac_ll_digi_reset();
53 DAC_EXIT_CRITICAL();
54
55 return ESP_OK;
56 }
57
dac_digi_controller_config(const dac_digi_config_t * cfg)58 esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg)
59 {
60 ESP_RETURN_ON_FALSE(cfg->mode <= DAC_CONV_ALTER, ESP_ERR_INVALID_ARG, TAG, "DAC mode error");
61 ESP_RETURN_ON_FALSE(cfg->interval > 0 && cfg->interval < 4096, ESP_ERR_INVALID_ARG, TAG, "DAC interval error");
62 ESP_RETURN_ON_FALSE(cfg->dig_clk.div_num < 256, ESP_ERR_INVALID_ARG, TAG, "DAC clk div_num error");
63 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");
64 ESP_RETURN_ON_FALSE(cfg->dig_clk.div_a < 64, ESP_ERR_INVALID_ARG, TAG, "DAC clk div_a error");
65 #ifdef CONFIG_PM_ENABLE
66 esp_err_t err;
67 if (s_dac_digi_lock == NULL) {
68 if (cfg->dig_clk.use_apll) {
69 err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "dac_dma", &s_dac_digi_lock);
70 } else {
71 err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "dac_dma", &s_dac_digi_lock);
72 }
73 if (err != ESP_OK) {
74 s_dac_digi_lock = NULL;
75 ESP_LOGE(TAG, "DAC-DMA pm lock error");
76 return err;
77 }
78 }
79 #endif //CONFIG_PM_ENABLE
80
81 DAC_ENTER_CRITICAL();
82 dac_ll_digi_set_convert_mode(cfg->mode == DAC_CONV_ALTER);
83 dac_ll_digi_set_trigger_interval(cfg->interval);
84 adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a);
85 adc_ll_digi_clk_sel(cfg->dig_clk.use_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT);
86 DAC_EXIT_CRITICAL();
87
88 return ESP_OK;
89 }
90
dac_digi_start(void)91 esp_err_t dac_digi_start(void)
92 {
93 #ifdef CONFIG_PM_ENABLE
94 ESP_RETURN_ON_FALSE(s_dac_digi_lock, ESP_FAIL, TAG, "Should start after call `dac_digi_controller_config`");
95 esp_pm_lock_acquire(s_dac_digi_lock);
96 #endif
97 DAC_ENTER_CRITICAL();
98 dac_ll_digi_enable_dma(true);
99 dac_ll_digi_trigger_output(true);
100 DAC_EXIT_CRITICAL();
101
102 return ESP_OK;
103 }
104
dac_digi_stop(void)105 esp_err_t dac_digi_stop(void)
106 {
107 #ifdef CONFIG_PM_ENABLE
108 if (s_dac_digi_lock) {
109 esp_pm_lock_release(s_dac_digi_lock);
110 }
111 #endif
112 DAC_ENTER_CRITICAL();
113 dac_ll_digi_trigger_output(false);
114 dac_ll_digi_enable_dma(false);
115 DAC_EXIT_CRITICAL();
116
117 return ESP_OK;
118 }
119
dac_digi_fifo_reset(void)120 esp_err_t dac_digi_fifo_reset(void)
121 {
122 DAC_ENTER_CRITICAL();
123 dac_ll_digi_fifo_reset();
124 DAC_EXIT_CRITICAL();
125
126 return ESP_OK;
127 }
128
dac_digi_reset(void)129 esp_err_t dac_digi_reset(void)
130 {
131 DAC_ENTER_CRITICAL();
132 dac_ll_digi_reset();
133 DAC_EXIT_CRITICAL();
134
135 return ESP_OK;
136 }
137