1 /*
2  * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*----------------------------------------------------------------------------------
8         This file contains ESP32 and ESP32S2 Depricated ADC APIs and functions
9 -----------------------------------------------------------------------------------*/
10 
11 #include "sdkconfig.h"
12 #include "esp_types.h"
13 #include "esp_log.h"
14 #include "esp_intr_alloc.h"
15 #include "driver/rtc_io.h"
16 #include "hal/adc_ll.h"
17 #include "hal/adc_types.h"
18 #ifdef CONFIG_PM_ENABLE
19 #include "esp_pm.h"
20 #endif
21 #include "adc.h"
22 #include "esp_private/adc_cali.h"
23 #include "freertos/FreeRTOS.h"
24 
25 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
26 #include "driver/adc_types_deprecated.h"
27 
28 static const char *ADC_TAG = "ADC";
29 
30 #define ADC_CHECK_RET(fun_ret) ({                  \
31     if (fun_ret != ESP_OK) {                                \
32         ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__);  \
33         return ESP_FAIL;                                    \
34     }                                                       \
35 })
36 
37 #define ADC_CHECK(a, str, ret_val) ({                                               \
38     if (!(a)) {                                                                     \
39         ESP_LOGE(ADC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str);                \
40         return (ret_val);                                                           \
41     }                                                                               \
42 })
43 
44 #define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
45 #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
46 
47 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
48 #define ADC_ENTER_CRITICAL()  portENTER_CRITICAL(&rtc_spinlock)
49 #define ADC_EXIT_CRITICAL()  portEXIT_CRITICAL(&rtc_spinlock)
50 
51 #ifdef CONFIG_PM_ENABLE
52 esp_pm_lock_handle_t adc_digi_arbiter_lock = NULL;
53 #endif  //CONFIG_PM_ENABLE
54 
55 
56 #if CONFIG_IDF_TARGET_ESP32
57 /*---------------------------------------------------------------
58         ESP32 Depricated ADC APIs and functions
59 ---------------------------------------------------------------*/
60 #define ADC_MEAS_NUM_LIM_DEFAULT      (1)
61 #define ADC_MAX_MEAS_NUM_DEFAULT      (255)
62 #define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT)
63 #define DIG_ADC_ATTEN_DEFUALT         (ADC_ATTEN_DB_11)
64 #define DIG_ADC_BIT_WIDTH_DEFUALT     (ADC_WIDTH_BIT_12)
65 
adc_digi_init(void)66 esp_err_t adc_digi_init(void)
67 {
68     ADC_ENTER_CRITICAL();
69     adc_hal_init();
70     ADC_EXIT_CRITICAL();
71     return ESP_OK;
72 }
73 
adc_digi_deinit(void)74 esp_err_t adc_digi_deinit(void)
75 {
76     adc_power_release();
77     ADC_ENTER_CRITICAL();
78     adc_hal_digi_deinit(NULL);
79     ADC_EXIT_CRITICAL();
80     return ESP_OK;
81 }
82 
83 /**
84  * Set adc output 16-bit-data format from digital controller.
85  *
86  * @param data_sel 1: [15] unit, [14:11] channel, [10:0] data, 11-bit-width at most. Only work under `ADC_LL_DIGI_CONV_BOTH_UNIT` or `ADC_LL_DIGI_CONV_ALTER_UNIT` mode.
87  *                 0: [15:12] channel, [11:0] data, 12-bit-width at most. Only work under `ADC_LL_DIGI_CONV_ONLY_ADC1` or `ADC_LL_DIGI_CONV_ONLY_ADC2` mode
88  * @note see `adc_ll_digi_pattern_table_t` for more detail of data bit width
89  */
adc_ll_digi_set_output_format(bool data_sel)90 static inline void adc_ll_digi_set_output_format(bool data_sel)
91 {
92     SYSCON.saradc_ctrl.data_sar_sel = data_sel;
93 }
94 
adc_ll_digi_prepare_pattern_table(adc_ll_num_t adc_n,uint32_t pattern_index,adc_digi_pattern_table_t pattern)95 static inline void adc_ll_digi_prepare_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t pattern)
96 {
97     uint32_t tab;
98     uint8_t index = pattern_index / 4;
99     uint8_t offset = (pattern_index % 4) * 8;
100     if (adc_n == ADC_NUM_1) {
101         tab = SYSCON.saradc_sar1_patt_tab[index];   // Read old register value
102         tab &= (~(0xFF000000 >> offset));           // clear old data
103         tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
104         SYSCON.saradc_sar1_patt_tab[index] = tab;   // Write back
105     } else { // adc_n == ADC_NUM_2
106         tab = SYSCON.saradc_sar2_patt_tab[index];   // Read old register value
107         tab &= (~(0xFF000000 >> offset));           // clear old data
108         tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
109         SYSCON.saradc_sar2_patt_tab[index] = tab;   // Write back
110     }
111 }
112 
adc_digi_controller_reg_set(const adc_digi_config_t * cfg)113 void adc_digi_controller_reg_set(const adc_digi_config_t *cfg)
114 {
115     /* On ESP32, only support ADC1 */
116     switch (cfg->conv_mode) {
117         case ADC_CONV_SINGLE_UNIT_1:
118             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC1);
119             break;
120         case ADC_CONV_SINGLE_UNIT_2:
121             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC2);
122             break;
123         case ADC_CONV_BOTH_UNIT:
124             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT);
125             break;
126         case ADC_CONV_ALTER_UNIT:
127             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ALTER_UNIT);
128             break;
129         default:
130             abort();
131     }
132 
133     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
134         adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_DIG);
135         if (cfg->adc1_pattern_len) {
136             adc_ll_digi_clear_pattern_table(ADC_NUM_1);
137             adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
138             for (uint32_t i = 0; i < cfg->adc1_pattern_len; i++) {
139                 adc_ll_digi_prepare_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
140             }
141         }
142     }
143     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
144         adc_ll_set_controller(ADC_NUM_2, ADC_LL_CTRL_DIG);
145         if (cfg->adc2_pattern_len) {
146             adc_ll_digi_clear_pattern_table(ADC_NUM_2);
147             adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
148             for (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) {
149                 adc_ll_digi_prepare_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
150             }
151         }
152     }
153     adc_ll_digi_set_output_format(cfg->format);
154     if (cfg->conv_limit_en) {
155         adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
156         adc_ll_digi_convert_limit_enable();
157     } else {
158         adc_ll_digi_convert_limit_disable();
159     }
160     adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC);
161 }
162 
adc_digi_controller_config(const adc_digi_config_t * config)163 esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
164 {
165     adc_power_acquire();
166     ADC_ENTER_CRITICAL();
167     adc_digi_controller_reg_set(config);
168     ADC_EXIT_CRITICAL();
169     return ESP_OK;
170 }
171 
adc_set_i2s_data_source(adc_i2s_source_t src)172 esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
173 {
174     ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG);
175     ADC_ENTER_CRITICAL();
176     adc_ll_digi_set_data_source(src);
177     ADC_EXIT_CRITICAL();
178     return ESP_OK;
179 }
180 
181 extern esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel);
adc_i2s_mode_init(adc_unit_t adc_unit,adc_channel_t channel)182 esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
183 {
184     if (adc_unit & ADC_UNIT_1) {
185         ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG);
186         ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
187     }
188     if (adc_unit & ADC_UNIT_2) {
189         ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG);
190         ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
191     }
192 
193     adc_digi_pattern_table_t adc1_pattern[1];
194     adc_digi_pattern_table_t adc2_pattern[1];
195     adc_digi_config_t dig_cfg = {
196         .conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT,
197         .conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT,
198         .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT,
199         .conv_mode = (adc_digi_convert_mode_t)adc_unit,
200     };
201 
202     if (adc_unit & ADC_UNIT_1) {
203         adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
204         adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
205         adc1_pattern[0].channel = channel;
206         dig_cfg.adc1_pattern_len = 1;
207         dig_cfg.adc1_pattern = adc1_pattern;
208     }
209     if (adc_unit & ADC_UNIT_2) {
210         adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
211         adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
212         adc2_pattern[0].channel = channel;
213         dig_cfg.adc2_pattern_len = 1;
214         dig_cfg.adc2_pattern = adc2_pattern;
215     }
216     adc_common_gpio_init(adc_unit, channel);
217     ADC_ENTER_CRITICAL();
218     adc_hal_init();
219     adc_digi_controller_reg_set(&dig_cfg);
220     ADC_EXIT_CRITICAL();
221 
222     return ESP_OK;
223 }
224 
225 #endif  //#if CONFIG_IDF_TARGET_ESP32
226 
227 #if CONFIG_IDF_TARGET_ESP32S2
228 /*---------------------------------------------------------------
229             ESP32S2 Depricated ADC functions and APIs
230 ---------------------------------------------------------------*/
adc_arbiter_config(adc_unit_t adc_unit,adc_arbiter_t * config)231 esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
232 {
233     if (adc_unit & ADC_UNIT_1) {
234         return ESP_ERR_NOT_SUPPORTED;
235     }
236     ADC_ENTER_CRITICAL();
237     adc_hal_arbiter_config(config);
238     ADC_EXIT_CRITICAL();
239     return ESP_OK;
240 }
241 
242 /**
243  * Enable interrupt of adc digital controller by bitmask.
244  *
245  * @param adc_n ADC unit.
246  * @param intr Interrupt bitmask.
247  */
adc_ll_digi_intr_enable(adc_ll_num_t adc_n,adc_digi_intr_t intr)248 static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
249 {
250     if (adc_n == ADC_NUM_1) {
251         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
252             APB_SARADC.int_ena.adc1_thres = 1;
253         }
254         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
255             APB_SARADC.int_ena.adc1_done = 1;
256         }
257     } else { // adc_n == ADC_NUM_2
258         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
259             APB_SARADC.int_ena.adc2_thres = 1;
260         }
261         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
262             APB_SARADC.int_ena.adc2_done = 1;
263         }
264     }
265 }
266 
adc_digi_intr_enable(adc_unit_t adc_unit,adc_digi_intr_t intr_mask)267 esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
268 {
269     ADC_ENTER_CRITICAL();
270     if (adc_unit & ADC_UNIT_1) {
271         adc_ll_digi_intr_enable(ADC_NUM_1, intr_mask);
272     }
273     if (adc_unit & ADC_UNIT_2) {
274         adc_ll_digi_intr_enable(ADC_NUM_2, intr_mask);
275     }
276     ADC_EXIT_CRITICAL();
277     return ESP_OK;
278 }
279 
280 /**
281  * Disable interrupt of adc digital controller by bitmask.
282  *
283  * @param adc_n ADC unit.
284  * @param intr Interrupt bitmask.
285  */
adc_ll_digi_intr_disable(adc_ll_num_t adc_n,adc_digi_intr_t intr)286 static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
287 {
288     if (adc_n == ADC_NUM_1) {
289         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
290             APB_SARADC.int_ena.adc1_thres = 0;
291         }
292         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
293             APB_SARADC.int_ena.adc1_done = 0;
294         }
295     } else { // adc_n == ADC_NUM_2
296         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
297             APB_SARADC.int_ena.adc2_thres = 0;
298         }
299         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
300             APB_SARADC.int_ena.adc2_done = 0;
301         }
302     }
303 }
304 
adc_digi_intr_disable(adc_unit_t adc_unit,adc_digi_intr_t intr_mask)305 esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
306 {
307     ADC_ENTER_CRITICAL();
308     if (adc_unit & ADC_UNIT_1) {
309         adc_ll_digi_intr_disable(ADC_NUM_1, intr_mask);
310     }
311     if (adc_unit & ADC_UNIT_2) {
312         adc_ll_digi_intr_disable(ADC_NUM_2, intr_mask);
313     }
314     ADC_EXIT_CRITICAL();
315     return ESP_OK;
316 }
317 
318 /**
319  * Clear interrupt of adc digital controller by bitmask.
320  *
321  * @param adc_n ADC unit.
322  * @param intr Interrupt bitmask.
323  */
adc_ll_digi_intr_clear(adc_ll_num_t adc_n,adc_digi_intr_t intr)324 static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t intr)
325 {
326     if (adc_n == ADC_NUM_1) {
327         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
328             APB_SARADC.int_clr.adc1_thres = 1;
329         }
330         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
331             APB_SARADC.int_clr.adc1_done = 1;
332         }
333     } else { // adc_n == ADC_NUM_2
334         if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
335             APB_SARADC.int_clr.adc2_thres = 1;
336         }
337         if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
338             APB_SARADC.int_clr.adc2_done = 1;
339         }
340     }
341 }
342 
adc_digi_intr_clear(adc_unit_t adc_unit,adc_digi_intr_t intr_mask)343 esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
344 {
345     ADC_ENTER_CRITICAL();
346     if (adc_unit & ADC_UNIT_1) {
347         adc_ll_digi_intr_clear(ADC_NUM_1, intr_mask);
348     }
349     if (adc_unit & ADC_UNIT_2) {
350         adc_ll_digi_intr_clear(ADC_NUM_2, intr_mask);
351     }
352     ADC_EXIT_CRITICAL();
353 
354     return ESP_OK;
355 }
356 
357 /**
358  * Get interrupt status mask of adc digital controller.
359  *
360  * @param adc_n ADC unit.
361  * @return
362  *     - intr Interrupt bitmask.
363  */
adc_ll_digi_get_intr_status(adc_ll_num_t adc_n)364 static inline uint32_t adc_ll_digi_get_intr_status(adc_ll_num_t adc_n)
365 {
366     uint32_t int_st = APB_SARADC.int_st.val;
367     uint32_t ret_msk = 0;
368 
369     if (adc_n == ADC_NUM_1) {
370         if (int_st & APB_SARADC_ADC1_DONE_INT_ST_M) {
371             ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
372         }
373         if (int_st & APB_SARADC_ADC1_THRES_INT_ST) {
374             ret_msk |= ADC_DIGI_INTR_MASK_MONITOR;
375         }
376     } else { // adc_n == ADC_NUM_2
377         if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) {
378             ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
379         }
380         if (int_st & APB_SARADC_ADC2_THRES_INT_ST_M) {
381             ret_msk |= ADC_DIGI_INTR_MASK_MONITOR;
382         }
383     }
384 
385     return ret_msk;
386 }
387 
adc_digi_intr_get_status(adc_unit_t adc_unit)388 uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit)
389 {
390     uint32_t ret = 0;
391     ADC_ENTER_CRITICAL();
392     if (adc_unit & ADC_UNIT_1) {
393         ret = adc_ll_digi_get_intr_status(ADC_NUM_1);
394     }
395     if (adc_unit & ADC_UNIT_2) {
396         ret = adc_ll_digi_get_intr_status(ADC_NUM_2);
397     }
398     ADC_EXIT_CRITICAL();
399     return ret;
400 }
401 
402 static uint8_t s_isr_registered = 0;
403 static intr_handle_t s_adc_isr_handle = NULL;
404 
adc_digi_isr_register(void (* fn)(void *),void * arg,int intr_alloc_flags)405 esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags)
406 {
407     ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG);
408     ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL);
409 
410     esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle);
411     if (ret == ESP_OK) {
412         s_isr_registered = 1;
413     }
414     return ret;
415 }
416 
adc_digi_isr_deregister(void)417 esp_err_t adc_digi_isr_deregister(void)
418 {
419     esp_err_t ret = ESP_FAIL;
420     if (s_isr_registered) {
421         ret = esp_intr_free(s_adc_isr_handle);
422         if (ret == ESP_OK) {
423             s_isr_registered = 0;
424         }
425     }
426     return ret;
427 }
428 
adc_digi_init(void)429 esp_err_t adc_digi_init(void)
430 {
431     adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
432     ADC_ENTER_CRITICAL();
433     adc_hal_init();
434     adc_hal_arbiter_config(&config);
435     ADC_EXIT_CRITICAL();
436 
437     adc_hal_calibration_init(ADC_NUM_1);
438     adc_hal_calibration_init(ADC_NUM_2);
439 
440     return ESP_OK;
441 }
442 
adc_digi_deinit(void)443 esp_err_t adc_digi_deinit(void)
444 {
445 #ifdef CONFIG_PM_ENABLE
446     if (adc_digi_arbiter_lock) {
447         esp_pm_lock_delete(adc_digi_arbiter_lock);
448         adc_digi_arbiter_lock = NULL;
449     }
450 #endif
451     adc_power_release();
452     ADC_ENTER_CRITICAL();
453     adc_hal_digi_deinit(NULL);
454     ADC_EXIT_CRITICAL();
455     return ESP_OK;
456 }
457 
458 /**
459  * @brief Reset FSM of adc digital controller.
460  *
461  * @return
462  *      - ESP_OK Success
463  */
adc_digi_reset(void)464 esp_err_t adc_digi_reset(void)
465 {
466     ADC_ENTER_CRITICAL();
467     adc_ll_digi_reset();
468     adc_ll_digi_clear_pattern_table(ADC_NUM_1);
469     adc_ll_digi_clear_pattern_table(ADC_NUM_2);
470     ADC_EXIT_CRITICAL();
471     return ESP_OK;
472 }
473 
474 /**
475  * Set adc output data format for digital controller.
476  *
477  * @param format Output data format.
478  */
adc_ll_digi_set_output_format(adc_digi_output_format_t format)479 static inline void adc_ll_digi_set_output_format(adc_digi_output_format_t format)
480 {
481     APB_SARADC.ctrl.data_sar_sel = format;
482 }
483 
adc_ll_digi_prepare_pattern_table(adc_ll_num_t adc_n,uint32_t pattern_index,adc_digi_pattern_table_t pattern)484 static inline void adc_ll_digi_prepare_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t pattern)
485 {
486     uint32_t tab;
487     uint8_t index = pattern_index / 4;
488     uint8_t offset = (pattern_index % 4) * 8;
489     if (adc_n == ADC_NUM_1) {
490         tab = APB_SARADC.sar1_patt_tab[index];  // Read old register value
491         tab &= (~(0xFF000000 >> offset));       // clear old data
492         tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
493         APB_SARADC.sar1_patt_tab[index] = tab;  // Write back
494     } else { // adc_n == ADC_NUM_2
495         tab = APB_SARADC.sar2_patt_tab[index];  // Read old register value
496         tab &= (~(0xFF000000 >> offset));       // clear old data
497         tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
498         APB_SARADC.sar2_patt_tab[index] = tab;  // Write back
499     }
500 }
501 
adc_digi_controller_reg_set(const adc_digi_config_t * cfg)502 static void adc_digi_controller_reg_set(const adc_digi_config_t *cfg)
503 {
504     /* Single channel mode or multi channel mode. */
505     switch (cfg->conv_mode) {
506         case ADC_CONV_SINGLE_UNIT_1:
507             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC1);
508             break;
509         case ADC_CONV_SINGLE_UNIT_2:
510             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC2);
511             break;
512         case ADC_CONV_BOTH_UNIT:
513             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT);
514             break;
515         case ADC_CONV_ALTER_UNIT:
516             adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ALTER_UNIT);
517             break;
518         default:
519             abort();
520     }
521 
522     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
523         if (cfg->adc1_pattern_len) {
524             adc_ll_digi_clear_pattern_table(ADC_NUM_1);
525             adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
526             for (uint32_t i = 0; i < cfg->adc1_pattern_len; i++) {
527                 adc_ll_digi_prepare_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
528             }
529         }
530     }
531     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
532         if (cfg->adc2_pattern_len) {
533             adc_ll_digi_clear_pattern_table(ADC_NUM_2);
534             adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
535             for (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) {
536                 adc_ll_digi_prepare_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
537             }
538         }
539     }
540     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
541         adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_DIG);
542     }
543     if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
544         adc_ll_set_controller(ADC_NUM_2, ADC_LL_CTRL_ARB);
545     }
546     adc_ll_digi_set_output_format(cfg->format);
547     if (cfg->conv_limit_en) {
548         adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
549         adc_ll_digi_convert_limit_enable();
550     } else {
551         adc_ll_digi_convert_limit_disable();
552     }
553 
554     adc_ll_digi_set_trigger_interval(cfg->interval);
555     adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a);
556     adc_ll_digi_clk_sel(cfg->dig_clk.use_apll);
557     adc_ll_digi_dma_set_eof_num(cfg->dma_eof_num);
558 }
559 
adc_digi_controller_config(const adc_digi_config_t * config)560 esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
561 {
562 #ifdef CONFIG_PM_ENABLE
563     esp_err_t err;
564     if (adc_digi_arbiter_lock == NULL) {
565         if (config->dig_clk.use_apll) {
566             err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "adc_dma", &adc_digi_arbiter_lock);
567         } else {
568             err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &adc_digi_arbiter_lock);
569         }
570         if (err != ESP_OK) {
571             adc_digi_arbiter_lock = NULL;
572             ESP_LOGE(ADC_TAG, "ADC-DMA pm lock error");
573             return err;
574         }
575     }
576 #endif //CONFIG_PM_ENABLE
577 
578     if (config->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
579         for (int i = 0; i < config->adc1_pattern_len; i++) {
580             adc_cal_offset(ADC_NUM_1, config->adc1_pattern[i].channel, config->adc1_pattern[i].atten);
581         }
582     }
583     if (config->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
584         for (int i = 0; i < config->adc2_pattern_len; i++) {
585             adc_cal_offset(ADC_NUM_2, config->adc2_pattern[i].channel, config->adc2_pattern[i].atten);
586         }
587     }
588 
589     /* If enable digtal controller, adc xpd should always on. */
590     adc_power_acquire();
591     ADC_ENTER_CRITICAL();
592     adc_digi_controller_reg_set(config);
593     ADC_EXIT_CRITICAL();
594     return ESP_OK;
595 }
596 #endif // #if CONFIG_IDF_TARGET_ESP32S2
597 
598 
599 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
600 /*---------------------------------------------------------------
601             ESP32S2 Depricated ADC functions and APIs
602 ---------------------------------------------------------------*/
adc_gpio_init(adc_unit_t adc_unit,adc_channel_t channel)603 esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel)
604 {
605     gpio_num_t gpio_num = 0;
606     //If called with `ADC_UNIT_BOTH (ADC_UNIT_1 | ADC_UNIT_2)`, both if blocks will be run
607     if (adc_unit & ADC_UNIT_1) {
608         ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
609         gpio_num = ADC_GET_IO_NUM(ADC_NUM_1, channel);
610         ADC_CHECK_RET(rtc_gpio_init(gpio_num));
611         ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
612         ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
613         ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
614     }
615     if (adc_unit & ADC_UNIT_2) {
616         ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
617         gpio_num = ADC_GET_IO_NUM(ADC_NUM_2, channel);
618         ADC_CHECK_RET(rtc_gpio_init(gpio_num));
619         ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
620         ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
621         ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
622     }
623 
624     return ESP_OK;
625 }
626 #endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
627