1 /*
2  * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <esp_types.h>
8 #include <stdlib.h>
9 #include <ctype.h>
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/semphr.h"
12 #include "freertos/timers.h"
13 #include "esp_log.h"
14 #include "esp_pm.h"
15 #include "soc/rtc.h"
16 #include "driver/rtc_io.h"
17 #include "sys/lock.h"
18 #include "driver/gpio.h"
19 #include "driver/adc.h"
20 #include "adc1_private.h"
21 #include "hal/adc_types.h"
22 #include "hal/adc_hal.h"
23 #include "hal/adc_hal_conf.h"
24 
25 #if SOC_DAC_SUPPORTED
26 #include "driver/dac.h"
27 #include "hal/dac_hal.h"
28 #endif
29 
30 #if CONFIG_IDF_TARGET_ESP32S3
31 #include "esp_efuse_rtc_calib.h"
32 #endif
33 
34 #define ADC_CHECK_RET(fun_ret) ({                  \
35     if (fun_ret != ESP_OK) {                                \
36         ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__);  \
37         return ESP_FAIL;                                    \
38     }                                                       \
39 })
40 
41 static const char *ADC_TAG = "ADC";
42 
43 #define ADC_CHECK(a, str, ret_val) ({                                               \
44     if (!(a)) {                                                                     \
45         ESP_LOGE(ADC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str);                \
46         return (ret_val);                                                           \
47     }                                                                               \
48 })
49 
50 #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
51 
52 #define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
53 
54 //////////////////////// Locks ///////////////////////////////////////////
55 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
56 
57 #define RTC_ENTER_CRITICAL()    portENTER_CRITICAL(&rtc_spinlock)
58 #define RTC_EXIT_CRITICAL()     portEXIT_CRITICAL(&rtc_spinlock)
59 #define DIGI_ENTER_CRITICAL()
60 #define DIGI_EXIT_CRITICAL()
61 
62 #define ADC_POWER_ENTER()       RTC_ENTER_CRITICAL()
63 #define ADC_POWER_EXIT()        RTC_EXIT_CRITICAL()
64 
65 #define DIGI_CONTROLLER_ENTER() DIGI_ENTER_CRITICAL()
66 #define DIGI_CONTROLLER_EXIT()  DIGI_EXIT_CRITICAL()
67 
68 #define SARADC1_ENTER()         RTC_ENTER_CRITICAL()
69 #define SARADC1_EXIT()          RTC_EXIT_CRITICAL()
70 
71 #define SARADC2_ENTER()         RTC_ENTER_CRITICAL()
72 #define SARADC2_EXIT()          RTC_EXIT_CRITICAL()
73 
74 //n stands for ADC unit: 1 for ADC1 and 2 for ADC2. Currently both unit touches the same registers
75 #define VREF_ENTER(n)           RTC_ENTER_CRITICAL()
76 #define VREF_EXIT(n)            RTC_EXIT_CRITICAL()
77 
78 #define FSM_ENTER()             RTC_ENTER_CRITICAL()
79 #define FSM_EXIT()              RTC_EXIT_CRITICAL()
80 
81 //TODO: IDF-3610
82 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
83 //prevent ADC1 being used by I2S dma and other tasks at the same time.
84 static _lock_t adc1_dma_lock;
85 #define SARADC1_ACQUIRE() _lock_acquire( &adc1_dma_lock )
86 #define SARADC1_RELEASE() _lock_release( &adc1_dma_lock )
87 #endif
88 
89 
90 /*
91 In ADC2, there're two locks used for different cases:
92 1. lock shared with app and Wi-Fi:
93    ESP32:
94         When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.
95    ESP32S2:
96         The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
97 
98 2. lock shared between tasks:
99    when several tasks sharing the ADC2, we want to guarantee
100    all the requests will be handled.
101    Since conversions are short (about 31us), app returns the lock very soon,
102    we use a spinlock to stand there waiting to do conversions one by one.
103 
104 adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
105 */
106 
107 #ifdef CONFIG_IDF_TARGET_ESP32
108 //prevent ADC2 being used by wifi and other tasks at the same time.
109 static _lock_t adc2_wifi_lock;
110 /** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock. */
111 #define SARADC2_ACQUIRE()       _lock_acquire( &adc2_wifi_lock )
112 #define SARADC2_RELEASE()       _lock_release( &adc2_wifi_lock )
113 #define SARADC2_TRY_ACQUIRE()   _lock_try_acquire( &adc2_wifi_lock )
114 #define SARADC2_LOCK_CHECK()    ((uint32_t *)adc2_wifi_lock != NULL)
115 
116 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
117 #define SARADC2_ACQUIRE()
118 #define SARADC2_RELEASE()
119 #define SARADC2_TRY_ACQUIRE()   (0)     //WIFI controller and rtc controller have independent parameter configuration.
120 #define SARADC2_LOCK_CHECK()    (true)
121 
122 #endif // CONFIG_IDF_TARGET_*
123 
124 #if CONFIG_IDF_TARGET_ESP32S2
125 #ifdef CONFIG_PM_ENABLE
126 static esp_pm_lock_handle_t s_adc2_arbiter_lock;
127 #endif  //CONFIG_PM_ENABLE
128 #endif  // !CONFIG_IDF_TARGET_ESP32
129 
130 
131 /*---------------------------------------------------------------
132                     ADC Common
133 ---------------------------------------------------------------*/
134 // ADC Power
135 
136 // This gets incremented when adc_power_acquire() is called, and decremented when
137 // adc_power_release() is called. ADC is powered down when the value reaches zero.
138 // Should be modified within critical section (ADC_ENTER/EXIT_CRITICAL).
139 static int s_adc_power_on_cnt;
140 
adc_power_on_internal(void)141 static void adc_power_on_internal(void)
142 {
143     /* Set the power always on to increase precision. */
144     adc_hal_set_power_manage(ADC_POWER_SW_ON);
145 }
146 
adc_power_acquire(void)147 void adc_power_acquire(void)
148 {
149     ADC_POWER_ENTER();
150     s_adc_power_on_cnt++;
151     if (s_adc_power_on_cnt == 1) {
152         adc_power_on_internal();
153     }
154     ADC_POWER_EXIT();
155 }
156 
adc_power_on(void)157 void adc_power_on(void)
158 {
159     ADC_POWER_ENTER();
160     adc_power_on_internal();
161     ADC_POWER_EXIT();
162 }
163 
adc_power_off_internal(void)164 static void adc_power_off_internal(void)
165 {
166 #if CONFIG_IDF_TARGET_ESP32
167     adc_hal_set_power_manage(ADC_POWER_SW_OFF);
168 #else
169     adc_hal_set_power_manage(ADC_POWER_BY_FSM);
170 #endif
171 }
172 
adc_power_release(void)173 void adc_power_release(void)
174 {
175     ADC_POWER_ENTER();
176     s_adc_power_on_cnt--;
177     /* Sanity check */
178     if (s_adc_power_on_cnt < 0) {
179         ADC_POWER_EXIT();
180         ESP_LOGE(ADC_TAG, "%s called, but s_adc_power_on_cnt == 0", __func__);
181         abort();
182     } else if (s_adc_power_on_cnt == 0) {
183         adc_power_off_internal();
184     }
185     ADC_POWER_EXIT();
186 }
187 
adc_power_off(void)188 void adc_power_off(void)
189 {
190     ADC_POWER_ENTER();
191     adc_power_off_internal();
192     ADC_POWER_EXIT();
193 }
194 
adc1_pad_get_io_num(adc1_channel_t channel,gpio_num_t * gpio_num)195 esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num)
196 {
197     ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
198 
199     int io = ADC_GET_IO_NUM(ADC_NUM_1, channel);
200     if (io < 0) {
201         return ESP_ERR_INVALID_ARG;
202     } else {
203         *gpio_num = (gpio_num_t)io;
204     }
205 
206     return ESP_OK;
207 }
208 
adc2_pad_get_io_num(adc2_channel_t channel,gpio_num_t * gpio_num)209 esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
210 {
211     ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
212 
213     int io = ADC_GET_IO_NUM(ADC_NUM_2, channel);
214     if (io < 0) {
215         return ESP_ERR_INVALID_ARG;
216     } else {
217         *gpio_num = (gpio_num_t)io;
218     }
219 
220     return ESP_OK;
221 }
222 
223 //------------------------------------------------------------RTC Single Read----------------------------------------------//
224 #if SOC_ADC_RTC_CTRL_SUPPORTED
225 
226 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
get_calibration_offset(adc_ll_num_t adc_n,adc_channel_t chan)227 static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
228 {
229     adc_atten_t atten = adc_ll_get_atten(adc_n, chan);
230     extern uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
231 
232     return adc_get_calibration_offset(adc_n, chan, atten);
233 }
234 #endif  //SOC_ADC_CALIBRATION_V1_SUPPORTED
235 
adc_set_clk_div(uint8_t clk_div)236 esp_err_t adc_set_clk_div(uint8_t clk_div)
237 {
238     DIGI_CONTROLLER_ENTER();
239     adc_ll_digi_set_clk_div(clk_div);
240     DIGI_CONTROLLER_EXIT();
241     return ESP_OK;
242 }
243 
adc_rtc_chan_init(adc_unit_t adc_unit)244 static void adc_rtc_chan_init(adc_unit_t adc_unit)
245 {
246     if (adc_unit & ADC_UNIT_1) {
247         /* Workaround: Disable the synchronization operation function of ADC1 and DAC.
248            If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage. */
249 #if SOC_DAC_SUPPORTED
250         dac_hal_rtc_sync_by_adc(false);
251 #endif
252         adc_hal_rtc_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
253         adc_ll_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
254 #ifdef CONFIG_IDF_TARGET_ESP32
255         adc_ll_hall_disable(); //Disable other peripherals.
256         adc_ll_amp_disable();  //Currently the LNA is not open, close it by default.
257 #endif
258     }
259     if (adc_unit & ADC_UNIT_2) {
260         adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
261         adc_hal_rtc_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
262         adc_ll_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
263     }
264 }
265 
266 /**
267  * This function is NOT an API.
268  * Now some to-be-deprecated APIs are using this function, so don't make it static for now.
269  * Will make this static on v5.0
270  */
adc_common_gpio_init(adc_unit_t adc_unit,adc_channel_t channel)271 esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel)
272 {
273     gpio_num_t gpio_num = 0;
274     //If called with `ADC_UNIT_BOTH (ADC_UNIT_1 | ADC_UNIT_2)`, both if blocks will be run
275     if (adc_unit & ADC_UNIT_1) {
276         ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
277         gpio_num = ADC_GET_IO_NUM(ADC_NUM_1, channel);
278         ADC_CHECK_RET(rtc_gpio_init(gpio_num));
279         ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
280         ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
281         ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
282     }
283     if (adc_unit & ADC_UNIT_2) {
284         ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
285         gpio_num = ADC_GET_IO_NUM(ADC_NUM_2, channel);
286         ADC_CHECK_RET(rtc_gpio_init(gpio_num));
287         ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
288         ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
289         ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
290     }
291 
292     return ESP_OK;
293 }
294 
adc_set_data_inv(adc_unit_t adc_unit,bool inv_en)295 esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en)
296 {
297     if (adc_unit & ADC_UNIT_1) {
298         SARADC1_ENTER();
299         adc_hal_rtc_output_invert(ADC_NUM_1, inv_en);
300         SARADC1_EXIT();
301     }
302     if (adc_unit & ADC_UNIT_2) {
303         SARADC2_ENTER();
304         adc_hal_rtc_output_invert(ADC_NUM_2, inv_en);
305         SARADC2_EXIT();
306     }
307 
308     return ESP_OK;
309 }
310 
adc_set_data_width(adc_unit_t adc_unit,adc_bits_width_t width_bit)311 esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit)
312 {
313 #if CONFIG_IDF_TARGET_ESP32
314     ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
315 #else
316     ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
317 #endif
318 
319     if (adc_unit & ADC_UNIT_1) {
320         SARADC1_ENTER();
321         adc_hal_rtc_set_output_format(ADC_NUM_1, width_bit);
322         SARADC1_EXIT();
323     }
324     if (adc_unit & ADC_UNIT_2) {
325         SARADC2_ENTER();
326         adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit);
327         SARADC2_EXIT();
328     }
329 
330     return ESP_OK;
331 }
332 
333 /**
334  * @brief Reset RTC controller FSM.
335  *
336  * @return
337  *      - ESP_OK Success
338  */
339 #if !CONFIG_IDF_TARGET_ESP32
adc_rtc_reset(void)340 esp_err_t adc_rtc_reset(void)
341 {
342     FSM_ENTER();
343     adc_ll_rtc_reset();
344     FSM_EXIT();
345     return ESP_OK;
346 }
347 #endif
348 
349 /*-------------------------------------------------------------------------------------
350  *                      ADC1
351  *------------------------------------------------------------------------------------*/
adc1_config_channel_atten(adc1_channel_t channel,adc_atten_t atten)352 esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
353 {
354     ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
355     ADC_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG);
356 
357     adc_common_gpio_init(ADC_UNIT_1, channel);
358     SARADC1_ENTER();
359     adc_rtc_chan_init(ADC_UNIT_1);
360     adc_hal_set_atten(ADC_NUM_1, channel, atten);
361     SARADC1_EXIT();
362 
363 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
364     adc_hal_calibration_init(ADC_NUM_1);
365 #endif
366 
367     return ESP_OK;
368 }
369 
adc1_config_width(adc_bits_width_t width_bit)370 esp_err_t adc1_config_width(adc_bits_width_t width_bit)
371 {
372 #if CONFIG_IDF_TARGET_ESP32
373     ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
374 #else
375     ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
376 #endif
377 
378     SARADC1_ENTER();
379     adc_hal_rtc_set_output_format(ADC_NUM_1, width_bit);
380     SARADC1_EXIT();
381 
382     return ESP_OK;
383 }
384 
adc1_dma_mode_acquire(void)385 esp_err_t adc1_dma_mode_acquire(void)
386 {
387     /* Use locks to avoid digtal and RTC controller conflicts.
388        for adc1, block until acquire the lock. */
389     SARADC1_ACQUIRE();
390     ESP_LOGD( ADC_TAG, "dma mode takes adc1 lock." );
391 
392     adc_power_acquire();
393 
394     SARADC1_ENTER();
395     /* switch SARADC into DIG channel */
396     adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_DIG);
397     SARADC1_EXIT();
398 
399     return ESP_OK;
400 }
401 
adc1_rtc_mode_acquire(void)402 esp_err_t adc1_rtc_mode_acquire(void)
403 {
404     /* Use locks to avoid digtal and RTC controller conflicts.
405        for adc1, block until acquire the lock. */
406     SARADC1_ACQUIRE();
407     adc_power_acquire();
408 
409     SARADC1_ENTER();
410     /* switch SARADC into RTC channel. */
411     adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_RTC);
412     SARADC1_EXIT();
413 
414     return ESP_OK;
415 }
416 
adc1_lock_release(void)417 esp_err_t adc1_lock_release(void)
418 {
419     ADC_CHECK((uint32_t *)adc1_dma_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE );
420     /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */
421 
422     adc_power_release();
423     SARADC1_RELEASE();
424     return ESP_OK;
425 }
426 
adc1_get_raw(adc1_channel_t channel)427 int adc1_get_raw(adc1_channel_t channel)
428 {
429     int adc_value;
430     ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
431     adc1_rtc_mode_acquire();
432 
433 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
434     // Get calibration value before going into critical section
435     uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
436     adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
437 #endif  //SOC_ADC_CALIBRATION_V1_SUPPORTED
438 
439     SARADC1_ENTER();
440 #ifdef CONFIG_IDF_TARGET_ESP32
441     adc_ll_hall_disable(); //Disable other peripherals.
442     adc_ll_amp_disable();  //Currently the LNA is not open, close it by default.
443 #endif
444     adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_RTC);    //Set controller
445     adc_hal_convert(ADC_NUM_1, channel, &adc_value);   //Start conversion, For ADC1, the data always valid.
446 #if !CONFIG_IDF_TARGET_ESP32
447     adc_ll_rtc_reset();    //Reset FSM of rtc controller
448 #endif
449     SARADC1_EXIT();
450 
451     adc1_lock_release();
452     return adc_value;
453 }
454 
adc1_get_voltage(adc1_channel_t channel)455 int adc1_get_voltage(adc1_channel_t channel)    //Deprecated. Use adc1_get_raw() instead
456 {
457     return adc1_get_raw(channel);
458 }
459 
460 #if SOC_ULP_SUPPORTED
adc1_ulp_enable(void)461 void adc1_ulp_enable(void)
462 {
463     adc_power_acquire();
464 
465     SARADC1_ENTER();
466     adc_ll_set_controller(ADC_NUM_1, ADC_LL_CTRL_ULP);
467     /* since most users do not need LNA and HALL with uLP, we disable them here
468        open them in the uLP if needed. */
469 #ifdef CONFIG_IDF_TARGET_ESP32
470     /* disable other peripherals. */
471     adc_ll_hall_disable();
472     adc_ll_amp_disable();
473 #endif
474     SARADC1_EXIT();
475 }
476 #endif
477 
478 /*---------------------------------------------------------------
479                     ADC2
480 ---------------------------------------------------------------*/
481 /** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/
adc2_wifi_acquire(void)482 esp_err_t adc2_wifi_acquire(void)
483 {
484     /* Wi-Fi module will use adc2. Use locks to avoid conflicts. */
485     SARADC2_ACQUIRE();
486     ESP_LOGD( ADC_TAG, "Wi-Fi takes adc2 lock." );
487     return ESP_OK;
488 }
489 
adc2_wifi_release(void)490 esp_err_t adc2_wifi_release(void)
491 {
492     ADC_CHECK(SARADC2_LOCK_CHECK(), "wifi release called before acquire", ESP_ERR_INVALID_STATE );
493     SARADC2_RELEASE();
494     ESP_LOGD( ADC_TAG, "Wi-Fi returns adc2 lock." );
495 
496     return ESP_OK;
497 }
498 
adc2_config_channel_atten(adc2_channel_t channel,adc_atten_t atten)499 esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
500 {
501     ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
502     ADC_CHECK(atten <= ADC_ATTEN_11db, "ADC2 Atten Err", ESP_ERR_INVALID_ARG);
503 
504     adc_common_gpio_init(ADC_UNIT_2, channel);
505 
506     if ( SARADC2_TRY_ACQUIRE() == -1 ) {
507         //try the lock, return if failed (wifi using).
508         return ESP_ERR_TIMEOUT;
509     }
510 
511     //avoid collision with other tasks
512     SARADC2_ENTER();
513     adc_rtc_chan_init(ADC_UNIT_2);
514     adc_hal_set_atten(ADC_NUM_2, channel, atten);
515     SARADC2_EXIT();
516 
517     SARADC2_RELEASE();
518 
519 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
520     adc_hal_calibration_init(ADC_NUM_2);
521 #endif
522 
523     return ESP_OK;
524 }
525 
adc2_init(void)526 static inline void adc2_init(void)
527 {
528 #if CONFIG_IDF_TARGET_ESP32S2
529 #ifdef CONFIG_PM_ENABLE
530     /* Lock APB clock. */
531     if (s_adc2_arbiter_lock == NULL) {
532         esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc2", &s_adc2_arbiter_lock);
533     }
534 #endif  //CONFIG_PM_ENABLE
535 #endif  //CONFIG_IDF_TARGET_ESP32S2
536 }
537 
adc2_dac_disable(adc2_channel_t channel)538 static inline void adc2_dac_disable( adc2_channel_t channel)
539 {
540 #if SOC_DAC_SUPPORTED
541 #ifdef CONFIG_IDF_TARGET_ESP32
542     if ( channel == ADC2_CHANNEL_8 ) { // the same as DAC channel 1
543         dac_output_disable(DAC_CHANNEL_1);
544     } else if ( channel == ADC2_CHANNEL_9 ) {
545         dac_output_disable(DAC_CHANNEL_2);
546     }
547 #else
548     if ( channel == ADC2_CHANNEL_6 ) { // the same as DAC channel 1
549         dac_output_disable(DAC_CHANNEL_1);
550     } else if ( channel == ADC2_CHANNEL_7 ) {
551         dac_output_disable(DAC_CHANNEL_2);
552     }
553 #endif
554 #endif // SOC_DAC_SUPPORTED
555 }
556 
557 /**
558  * @note For ESP32S2:
559  *       The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
560  *       Or, the RTC controller will fail when get raw data.
561  *       This issue does not occur on digital controllers (DMA mode), and the hardware guarantees that there will be no errors.
562  */
adc2_get_raw(adc2_channel_t channel,adc_bits_width_t width_bit,int * raw_out)563 esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out)
564 {
565     esp_err_t ret = ESP_OK;
566     int adc_value = 0;
567 
568     ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG);
569     ADC_CHECK(channel < ADC2_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
570 #if CONFIG_IDF_TARGET_ESP32
571     ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
572 #else
573     ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
574 #endif
575 
576 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
577     // Get calibration value before going into critical section
578     uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
579     adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
580 #endif  //SOC_ADC_CALIBRATION_V1_SUPPORTED
581 
582     if ( SARADC2_TRY_ACQUIRE() == -1 ) {
583         //try the lock, return if failed (wifi using).
584         return ESP_ERR_TIMEOUT;
585     }
586     adc_power_acquire();         //in critical section with whole rtc module
587 
588     //avoid collision with other tasks
589     adc2_init();   // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
590     SARADC2_ENTER();
591 
592 #if SOC_ADC_ARBITER_SUPPORTED
593     adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
594     adc_hal_arbiter_config(&config);
595 #endif
596 
597 #ifdef CONFIG_ADC_DISABLE_DAC
598     adc2_dac_disable(channel);      //disable other peripherals
599 #endif
600     adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit);
601 
602 #if CONFIG_IDF_TARGET_ESP32
603     adc_ll_set_controller(ADC_NUM_2, ADC_LL_CTRL_RTC);// set controller
604 #else
605     adc_ll_set_controller(ADC_NUM_2, ADC_LL_CTRL_ARB);// set controller
606 #endif
607 
608 #if CONFIG_IDF_TARGET_ESP32S2
609 #ifdef CONFIG_PM_ENABLE
610     if (s_adc2_arbiter_lock) {
611         esp_pm_lock_acquire(s_adc2_arbiter_lock);
612     }
613 #endif //CONFIG_PM_ENABLE
614 #endif //CONFIG_IDF_TARGET_ESP32
615 
616     ret = adc_hal_convert(ADC_NUM_2, channel, &adc_value);
617     if (ret != ESP_OK) {
618         adc_value = -1;
619     }
620 
621 #if CONFIG_IDF_TARGET_ESP32S2
622 #ifdef CONFIG_PM_ENABLE
623     /* Release APB clock. */
624     if (s_adc2_arbiter_lock) {
625         esp_pm_lock_release(s_adc2_arbiter_lock);
626     }
627 #endif //CONFIG_PM_ENABLE
628 #endif //CONFIG_IDF_TARGET_ESP32
629     SARADC2_EXIT();
630 
631     adc_power_release();
632     SARADC2_RELEASE();
633 
634     *raw_out = adc_value;
635     return ret;
636 }
637 
adc2_vref_to_gpio(gpio_num_t gpio)638 esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
639 {
640     return adc_vref_to_gpio(ADC_UNIT_2, gpio);
641 }
642 
adc_vref_to_gpio(adc_unit_t adc_unit,gpio_num_t gpio)643 esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
644 {
645 #ifdef CONFIG_IDF_TARGET_ESP32
646     if (adc_unit & ADC_UNIT_1) {
647         return ESP_ERR_INVALID_ARG;
648     }
649 #endif
650     adc2_channel_t ch = ADC2_CHANNEL_MAX;
651     /* Check if the GPIO supported. */
652     for (int i = 0; i < ADC2_CHANNEL_MAX; i++) {
653         if (gpio == ADC_GET_IO_NUM(ADC_NUM_2, i)) {
654             ch = i;
655             break;
656         }
657     }
658     if (ch == ADC2_CHANNEL_MAX) {
659         return ESP_ERR_INVALID_ARG;
660     }
661 
662     adc_power_acquire();
663     if (adc_unit & ADC_UNIT_1) {
664         VREF_ENTER(1);
665         adc_hal_vref_output(ADC_NUM_1, ch, true);
666         VREF_EXIT(1);
667     } else if (adc_unit & ADC_UNIT_2) {
668         VREF_ENTER(2);
669         adc_hal_vref_output(ADC_NUM_2, ch, true);
670         VREF_EXIT(2);
671     }
672 
673     //Configure RTC gpio, Only ADC2's channels IO are supported to output reference voltage.
674     adc_common_gpio_init(ADC_UNIT_2, ch);
675     return ESP_OK;
676 }
677 
678 #endif //SOC_ADC_RTC_CTRL_SUPPORTED
679