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