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