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