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