1 /*
2  * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <esp_types.h>
8 #include <stdlib.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include "sdkconfig.h"
12 #include "esp_intr_alloc.h"
13 #include "esp_log.h"
14 #include "esp_pm.h"
15 #include "esp_check.h"
16 #include "sys/lock.h"
17 #include "freertos/FreeRTOS.h"
18 #include "freertos/semphr.h"
19 #include "freertos/timers.h"
20 #include "freertos/ringbuf.h"
21 #include "esp_private/periph_ctrl.h"
22 #include "esp_private/adc_share_hw_ctrl.h"
23 #include "esp_private/sar_periph_ctrl.h"
24 #include "hal/adc_types.h"
25 #include "hal/adc_hal.h"
26 #include "hal/dma_types.h"
27 #include "hal/adc_hal_common.h"
28 
29 #include "driver/gpio.h"
30 #include "driver/adc_types_legacy.h"
31 
32 //For calibration
33 #if CONFIG_IDF_TARGET_ESP32S2
34 #include "esp_efuse_rtc_table.h"
35 #elif SOC_ADC_CALIBRATION_V1_SUPPORTED
36 #include "esp_efuse_rtc_calib.h"
37 #endif
38 //For DMA
39 #if SOC_GDMA_SUPPORTED
40 #include "esp_private/gdma.h"
41 #elif CONFIG_IDF_TARGET_ESP32S2
42 #include "hal/spi_types.h"
43 #include "esp_private/spi_common_internal.h"
44 #elif CONFIG_IDF_TARGET_ESP32
45 #include "driver/i2s_types.h"
46 #include "soc/i2s_periph.h"
47 #include "esp_private/i2s_platform.h"
48 #endif
49 
50 static const char *ADC_TAG = "ADC";
51 
52 #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
53 
54 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
55 #define ADC_ENTER_CRITICAL()  portENTER_CRITICAL(&rtc_spinlock)
56 #define ADC_EXIT_CRITICAL()  portEXIT_CRITICAL(&rtc_spinlock)
57 
58 #define INTERNAL_BUF_NUM 5
59 
60 /*---------------------------------------------------------------
61                     Digital Controller Context
62 ---------------------------------------------------------------*/
63 typedef struct adc_digi_context_t {
64     uint8_t                         *rx_dma_buf;                //dma buffer
65     adc_hal_dma_ctx_t               hal;                        //hal context
66 #if SOC_GDMA_SUPPORTED
67     gdma_channel_handle_t           rx_dma_channel;             //dma rx channel handle
68 #elif CONFIG_IDF_TARGET_ESP32S2
69     spi_host_device_t               spi_host;                   //ADC uses this SPI DMA
70     intr_handle_t                   intr_hdl;                   //Interrupt handler
71 #elif CONFIG_IDF_TARGET_ESP32
72     i2s_port_t                      i2s_host;                   //ADC uses this I2S DMA
73     intr_handle_t                   intr_hdl;                   //Interrupt handler
74 #endif
75     RingbufHandle_t                 ringbuf_hdl;                //RX ringbuffer handler
76     intptr_t                        rx_eof_desc_addr;           //eof descriptor address of RX channel
77     bool                            ringbuf_overflow_flag;      //1: ringbuffer overflow
78     bool                            driver_start_flag;          //1: driver is started; 0: driver is stoped
79     bool                            use_adc1;                   //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
80     bool                            use_adc2;                   //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not.
81     adc_atten_t                     adc1_atten;                 //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
82     adc_atten_t                     adc2_atten;                 //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
83     adc_hal_digi_ctrlr_cfg_t             hal_digi_ctrlr_cfg;         //Hal digital controller configuration
84     esp_pm_lock_handle_t            pm_lock;                    //For power management
85 } adc_digi_context_t;
86 
87 static adc_digi_context_t *s_adc_digi_ctx = NULL;
88 #ifdef CONFIG_PM_ENABLE
89 //Only for deprecated API
90 extern esp_pm_lock_handle_t adc_digi_arbiter_lock;
91 #endif  //CONFIG_PM_ENABLE
92 
93 /*---------------------------------------------------------------
94                    ADC Continuous Read Mode (via DMA)
95 ---------------------------------------------------------------*/
96 //Function to address transaction
97 static bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx);
98 
99 #if SOC_GDMA_SUPPORTED
100 static bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data);
101 #else
102 static void adc_dma_intr_handler(void *arg);
103 #endif
104 
adc_digi_get_io_num(adc_unit_t adc_unit,uint8_t adc_channel)105 static int8_t adc_digi_get_io_num(adc_unit_t adc_unit, uint8_t adc_channel)
106 {
107     assert(adc_unit < SOC_ADC_PERIPH_NUM);
108     uint8_t adc_n = (adc_unit == ADC_UNIT_1) ? 0 : 1;
109     return adc_channel_io_map[adc_n][adc_channel];
110 }
111 
adc_digi_gpio_init(adc_unit_t adc_unit,uint16_t channel_mask)112 static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask)
113 {
114     esp_err_t ret = ESP_OK;
115     uint64_t gpio_mask = 0;
116     uint32_t n = 0;
117     int8_t io = 0;
118 
119     while (channel_mask) {
120         if (channel_mask & 0x1) {
121             io = adc_digi_get_io_num(adc_unit, n);
122             if (io < 0) {
123                 return ESP_ERR_INVALID_ARG;
124             }
125             gpio_mask |= BIT64(io);
126         }
127         channel_mask = channel_mask >> 1;
128         n++;
129     }
130 
131     gpio_config_t cfg = {
132         .pin_bit_mask = gpio_mask,
133         .mode = GPIO_MODE_DISABLE,
134     };
135     ret = gpio_config(&cfg);
136 
137     return ret;
138 }
139 
adc_digi_deinitialize(void)140 esp_err_t adc_digi_deinitialize(void)
141 {
142     if (!s_adc_digi_ctx) {
143         return ESP_ERR_INVALID_STATE;
144     }
145 
146     if (s_adc_digi_ctx->driver_start_flag != 0) {
147         ESP_LOGE(ADC_TAG, "The driver is not stopped");
148         return ESP_ERR_INVALID_STATE;
149     }
150 
151     if (s_adc_digi_ctx->ringbuf_hdl) {
152         vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl);
153         s_adc_digi_ctx->ringbuf_hdl = NULL;
154     }
155 
156 #if CONFIG_PM_ENABLE
157     if (s_adc_digi_ctx->pm_lock) {
158         esp_pm_lock_delete(s_adc_digi_ctx->pm_lock);
159     }
160 #endif  //CONFIG_PM_ENABLE
161 
162     free(s_adc_digi_ctx->rx_dma_buf);
163     free(s_adc_digi_ctx->hal.rx_desc);
164     free(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern);
165 #if SOC_GDMA_SUPPORTED
166     gdma_disconnect(s_adc_digi_ctx->rx_dma_channel);
167     gdma_del_channel(s_adc_digi_ctx->rx_dma_channel);
168 #elif CONFIG_IDF_TARGET_ESP32S2
169     esp_intr_free(s_adc_digi_ctx->intr_hdl);
170     spicommon_dma_chan_free(s_adc_digi_ctx->spi_host);
171     spicommon_periph_free(s_adc_digi_ctx->spi_host);
172 #elif CONFIG_IDF_TARGET_ESP32
173     esp_intr_free(s_adc_digi_ctx->intr_hdl);
174     i2s_platform_release_occupation(s_adc_digi_ctx->i2s_host);
175 #endif
176     free(s_adc_digi_ctx);
177     s_adc_digi_ctx = NULL;
178 
179     periph_module_disable(PERIPH_SARADC_MODULE);
180 
181     return ESP_OK;
182 }
183 
adc_digi_initialize(const adc_digi_init_config_t * init_config)184 esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
185 {
186     esp_err_t ret = ESP_OK;
187     ESP_RETURN_ON_FALSE((init_config->conv_num_each_intr % SOC_ADC_DIGI_DATA_BYTES_PER_CONV == 0), ESP_ERR_INVALID_ARG, ADC_TAG, "conv_frame_size should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`");
188 
189     s_adc_digi_ctx = calloc(1, sizeof(adc_digi_context_t));
190     if (s_adc_digi_ctx == NULL) {
191         ret = ESP_ERR_NO_MEM;
192         goto cleanup;
193     }
194 
195     //ringbuffer
196     s_adc_digi_ctx->ringbuf_hdl = xRingbufferCreate(init_config->max_store_buf_size, RINGBUF_TYPE_BYTEBUF);
197     if (!s_adc_digi_ctx->ringbuf_hdl) {
198         ret = ESP_ERR_NO_MEM;
199         goto cleanup;
200     }
201 
202     //malloc internal buffer used by DMA
203     s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, init_config->conv_num_each_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
204     if (!s_adc_digi_ctx->rx_dma_buf) {
205         ret = ESP_ERR_NO_MEM;
206         goto cleanup;
207     }
208 
209     //malloc dma descriptor
210     uint32_t dma_desc_num_per_frame = (init_config->conv_num_each_intr + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
211     uint32_t dma_desc_max_num = dma_desc_num_per_frame * INTERNAL_BUF_NUM;
212     s_adc_digi_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * dma_desc_max_num, MALLOC_CAP_DMA);
213     if (!s_adc_digi_ctx->hal.rx_desc) {
214         ret = ESP_ERR_NO_MEM;
215         goto cleanup;
216     }
217 
218     //malloc pattern table
219     s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern = calloc(1, SOC_ADC_PATT_LEN_MAX * sizeof(adc_digi_pattern_config_t));
220     if (!s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern) {
221         ret = ESP_ERR_NO_MEM;
222         goto cleanup;
223     }
224 
225 #if CONFIG_PM_ENABLE
226     ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_ctx->pm_lock);
227     if (ret != ESP_OK) {
228         goto cleanup;
229     }
230 #endif //CONFIG_PM_ENABLE
231 
232     //init gpio pins
233     if (init_config->adc1_chan_mask) {
234         ret = adc_digi_gpio_init(ADC_UNIT_1, init_config->adc1_chan_mask);
235         if (ret != ESP_OK) {
236             goto cleanup;
237         }
238     }
239     if (init_config->adc2_chan_mask) {
240         ret = adc_digi_gpio_init(ADC_UNIT_2, init_config->adc2_chan_mask);
241         if (ret != ESP_OK) {
242             goto cleanup;
243         }
244     }
245 
246 #if SOC_GDMA_SUPPORTED
247     //alloc rx gdma channel
248     gdma_channel_alloc_config_t rx_alloc_config = {
249         .direction = GDMA_CHANNEL_DIRECTION_RX,
250     };
251     ret = gdma_new_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel);
252     if (ret != ESP_OK) {
253         goto cleanup;
254     }
255     gdma_connect(s_adc_digi_ctx->rx_dma_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_ADC, 0));
256 
257     gdma_strategy_config_t strategy_config = {
258         .auto_update_desc = true,
259         .owner_check = true
260     };
261     gdma_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config);
262 
263     gdma_rx_event_callbacks_t cbs = {
264         .on_recv_eof = adc_dma_in_suc_eof_callback
265     };
266     gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx);
267 
268     int dma_chan;
269     gdma_get_channel_id(s_adc_digi_ctx->rx_dma_channel, &dma_chan);
270 
271 #elif CONFIG_IDF_TARGET_ESP32S2
272     //ADC utilises SPI3 DMA on ESP32S2
273     bool spi_success = false;
274     uint32_t dma_chan = 0;
275 
276     spi_success = spicommon_periph_claim(SPI3_HOST, "adc");
277     ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan);
278     if (ret == ESP_OK) {
279         s_adc_digi_ctx->spi_host = SPI3_HOST;
280     }
281     if (!spi_success || (s_adc_digi_ctx->spi_host != SPI3_HOST)) {
282         goto cleanup;
283     }
284 
285     ret = esp_intr_alloc(spicommon_irqdma_source_for_host(s_adc_digi_ctx->spi_host), 0, adc_dma_intr_handler,
286                         (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl);
287     if (ret != ESP_OK) {
288         goto cleanup;
289     }
290 
291 #elif CONFIG_IDF_TARGET_ESP32
292     //ADC utilises I2S0 DMA on ESP32
293     uint32_t dma_chan = 0;
294     ret = i2s_platform_acquire_occupation(I2S_NUM_0, "adc");
295     if (ret != ESP_OK) {
296         goto cleanup;
297     }
298 
299     s_adc_digi_ctx->i2s_host = I2S_NUM_0;
300     ret = esp_intr_alloc(i2s_periph_signal[s_adc_digi_ctx->i2s_host].irq, 0, adc_dma_intr_handler,
301                         (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl);
302     if (ret != ESP_OK) {
303         goto cleanup;
304     }
305 #endif
306 
307     adc_hal_dma_config_t config = {
308 #if SOC_GDMA_SUPPORTED
309         .dev = (void *)GDMA_LL_GET_HW(0),
310 #elif CONFIG_IDF_TARGET_ESP32S2
311         .dev = (void *)SPI_LL_GET_HW(s_adc_digi_ctx->spi_host),
312 #elif CONFIG_IDF_TARGET_ESP32
313         .dev = (void *)I2S_LL_GET_HW(s_adc_digi_ctx->i2s_host),
314 #endif
315         .eof_desc_num = INTERNAL_BUF_NUM,
316         .eof_step = dma_desc_num_per_frame,
317         .dma_chan = dma_chan,
318         .eof_num = init_config->conv_num_each_intr / SOC_ADC_DIGI_DATA_BYTES_PER_CONV
319     };
320     adc_hal_dma_ctx_config(&s_adc_digi_ctx->hal, &config);
321 
322     //enable ADC digital part
323     periph_module_enable(PERIPH_SARADC_MODULE);
324     //reset ADC digital part
325     periph_module_reset(PERIPH_SARADC_MODULE);
326 
327 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
328     adc_hal_calibration_init(ADC_UNIT_1);
329     adc_hal_calibration_init(ADC_UNIT_2);
330 #endif  //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
331 
332     return ret;
333 
334 cleanup:
335     adc_digi_deinitialize();
336     return ret;
337 }
338 
339 #if SOC_GDMA_SUPPORTED
adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan,gdma_event_data_t * event_data,void * user_data)340 static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
341 {
342     assert(event_data);
343     s_adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr;
344     return s_adc_dma_intr(user_data);
345 }
346 #else
adc_dma_intr_handler(void * arg)347 static IRAM_ATTR void adc_dma_intr_handler(void *arg)
348 {
349     adc_digi_context_t *ctx = (adc_digi_context_t *)arg;
350     bool need_yield = false;
351 
352     bool conversion_finish = adc_hal_check_event(&ctx->hal, ADC_HAL_DMA_INTR_MASK);
353     if (conversion_finish) {
354         adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
355 
356         intptr_t desc_addr = adc_hal_get_desc_addr(&ctx->hal);
357 
358         ctx->rx_eof_desc_addr = desc_addr;
359         need_yield = s_adc_dma_intr(ctx);
360     }
361 
362     if (need_yield) {
363         portYIELD_FROM_ISR();
364     }
365 }
366 #endif
367 
s_adc_dma_intr(adc_digi_context_t * adc_digi_ctx)368 static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx)
369 {
370     portBASE_TYPE taskAwoken = 0;
371     BaseType_t ret;
372     adc_hal_dma_desc_status_t status = false;
373     uint8_t *finished_buffer = NULL;
374     uint32_t finished_size = 0;
375 
376     while (1) {
377         status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, &finished_buffer, &finished_size);
378         if (status != ADC_HAL_DMA_DESC_VALID) {
379             break;
380         }
381 
382         ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken);
383         if (ret == pdFALSE) {
384             //ringbuffer overflow
385             adc_digi_ctx->ringbuf_overflow_flag = 1;
386         }
387     }
388 
389     return (taskAwoken == pdTRUE);
390 }
391 
adc_digi_start(void)392 esp_err_t adc_digi_start(void)
393 {
394 
395     if (s_adc_digi_ctx->driver_start_flag != 0) {
396         ESP_LOGE(ADC_TAG, "The driver is already started");
397         return ESP_ERR_INVALID_STATE;
398     }
399     sar_periph_ctrl_adc_continuous_power_acquire();
400     //reset flags
401     s_adc_digi_ctx->ringbuf_overflow_flag = 0;
402     s_adc_digi_ctx->driver_start_flag = 1;
403     if (s_adc_digi_ctx->use_adc1) {
404         adc_lock_acquire(ADC_UNIT_1);
405     }
406     if (s_adc_digi_ctx->use_adc2) {
407         adc_lock_acquire(ADC_UNIT_2);
408     }
409 
410 #if CONFIG_PM_ENABLE
411     // Lock APB frequency while ADC driver is in use
412     esp_pm_lock_acquire(s_adc_digi_ctx->pm_lock);
413 #endif
414 
415 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
416     if (s_adc_digi_ctx->use_adc1) {
417         adc_set_hw_calibration_code(ADC_UNIT_1, s_adc_digi_ctx->adc1_atten);
418     }
419     if (s_adc_digi_ctx->use_adc2) {
420         adc_set_hw_calibration_code(ADC_UNIT_2, s_adc_digi_ctx->adc2_atten);
421     }
422 #endif  //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
423 
424 #if SOC_ADC_ARBITER_SUPPORTED
425     adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
426     adc_hal_arbiter_config(&config);
427 #endif  //#if SOC_ADC_ARBITER_SUPPORTED
428 
429     adc_hal_set_controller(ADC_UNIT_1, ADC_HAL_CONTINUOUS_READ_MODE);
430     adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE);
431 
432     adc_hal_digi_init(&s_adc_digi_ctx->hal);
433     adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg);
434 
435     //start conversion
436     adc_hal_digi_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf);
437 
438     return ESP_OK;
439 }
440 
adc_digi_stop(void)441 esp_err_t adc_digi_stop(void)
442 {
443     if (s_adc_digi_ctx->driver_start_flag != 1) {
444         ESP_LOGE(ADC_TAG, "The driver is already stopped");
445         return ESP_ERR_INVALID_STATE;
446     }
447     s_adc_digi_ctx->driver_start_flag = 0;
448 
449     //disable the in suc eof intrrupt
450     adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
451     //clear the in suc eof interrupt
452     adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, ADC_HAL_DMA_INTR_MASK);
453     //stop ADC
454     adc_hal_digi_stop(&s_adc_digi_ctx->hal);
455 
456     adc_hal_digi_deinit(&s_adc_digi_ctx->hal);
457 #if CONFIG_PM_ENABLE
458     if (s_adc_digi_ctx->pm_lock) {
459         esp_pm_lock_release(s_adc_digi_ctx->pm_lock);
460     }
461 #endif  //CONFIG_PM_ENABLE
462 
463     if (s_adc_digi_ctx->use_adc2) {
464         adc_lock_release(ADC_UNIT_2);
465     }
466     if (s_adc_digi_ctx->use_adc1) {
467         adc_lock_release(ADC_UNIT_1);
468     }
469     sar_periph_ctrl_adc_continuous_power_release();
470 
471     return ESP_OK;
472 }
473 
adc_digi_read_bytes(uint8_t * buf,uint32_t length_max,uint32_t * out_length,uint32_t timeout_ms)474 esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_length, uint32_t timeout_ms)
475 {
476     TickType_t ticks_to_wait;
477     esp_err_t ret = ESP_OK;
478     uint8_t *data = NULL;
479     size_t size = 0;
480 
481     ticks_to_wait = timeout_ms / portTICK_PERIOD_MS;
482     if (timeout_ms == ADC_MAX_DELAY) {
483         ticks_to_wait = portMAX_DELAY;
484     }
485 
486     data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max);
487     if (!data) {
488         ESP_LOGV(ADC_TAG, "No data, increase timeout or reduce conv_num_each_intr");
489         ret = ESP_ERR_TIMEOUT;
490         *out_length = 0;
491         return ret;
492     }
493 
494     memcpy(buf, data, size);
495     vRingbufferReturnItem(s_adc_digi_ctx->ringbuf_hdl, data);
496     assert((size % 4) == 0);
497     *out_length = size;
498 
499     if (s_adc_digi_ctx->ringbuf_overflow_flag) {
500         ret = ESP_ERR_INVALID_STATE;
501     }
502 
503     return ret;
504 }
505 
506 /*---------------------------------------------------------------
507                     Digital controller setting
508 ---------------------------------------------------------------*/
adc_digi_controller_configure(const adc_digi_configuration_t * config)509 esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config)
510 {
511     if (!s_adc_digi_ctx) {
512         return ESP_ERR_INVALID_STATE;
513     }
514 
515     //Pattern related check
516     ESP_RETURN_ON_FALSE(config->pattern_num <= SOC_ADC_PATT_LEN_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "Max pattern num is %d", SOC_ADC_PATT_LEN_MAX);
517 #if CONFIG_IDF_TARGET_ESP32
518     for (int i = 0; i < config->pattern_num; i++) {
519         ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width >= SOC_ADC_DIGI_MIN_BITWIDTH && config->adc_pattern->bit_width <= SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
520         ESP_RETURN_ON_FALSE(config->adc_pattern[i].unit == 0, ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode");
521     }
522 #else
523     for (int i = 0; i < config->pattern_num; i++) {
524         ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width == SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
525     }
526 #endif
527     ESP_RETURN_ON_FALSE(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC sampling frequency out of range");
528 
529 #if CONFIG_IDF_TARGET_ESP32
530     ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1");
531 #elif CONFIG_IDF_TARGET_ESP32S2
532     if (config->conv_mode == ADC_CONV_BOTH_UNIT || config->conv_mode == ADC_CONV_ALTER_UNIT) {
533         ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2");
534     } else if (config->conv_mode == ADC_CONV_SINGLE_UNIT_1 || config->conv_mode == ADC_CONV_SINGLE_UNIT_2) {
535         ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1");
536     }
537 #else
538     ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2");
539 #endif
540 
541     s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern_len = config->pattern_num;
542     s_adc_digi_ctx->hal_digi_ctrlr_cfg.sample_freq_hz = config->sample_freq_hz;
543     s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_mode = config->conv_mode;
544     memcpy(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern, config->adc_pattern, config->pattern_num * sizeof(adc_digi_pattern_config_t));
545 
546     const int atten_uninitialized = 999;
547     s_adc_digi_ctx->adc1_atten = atten_uninitialized;
548     s_adc_digi_ctx->adc2_atten = atten_uninitialized;
549     s_adc_digi_ctx->use_adc1 = 0;
550     s_adc_digi_ctx->use_adc2 = 0;
551     for (int i = 0; i < config->pattern_num; i++) {
552         const adc_digi_pattern_config_t *pat = &config->adc_pattern[i];
553         if (pat->unit == ADC_UNIT_1) {
554             s_adc_digi_ctx->use_adc1 = 1;
555 
556             if (s_adc_digi_ctx->adc1_atten == atten_uninitialized) {
557                 s_adc_digi_ctx->adc1_atten = pat->atten;
558             } else if (s_adc_digi_ctx->adc1_atten != pat->atten) {
559                 return ESP_ERR_INVALID_ARG;
560             }
561         } else if (pat->unit == ADC_UNIT_2) {
562             //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver
563             s_adc_digi_ctx->use_adc2 = 1;
564 
565             if (s_adc_digi_ctx->adc2_atten == atten_uninitialized) {
566                 s_adc_digi_ctx->adc2_atten = pat->atten;
567             } else if (s_adc_digi_ctx->adc2_atten != pat->atten) {
568                 return ESP_ERR_INVALID_ARG;
569             }
570         }
571     }
572 
573     return ESP_OK;
574 }
575 
576 /**
577  * @brief This function will be called during start up, to check that adc_continuous driver is not running along with the legacy adc_continuous driver
578  */
check_adc_continuous_driver_conflict(void)579 static void check_adc_continuous_driver_conflict(void)
580 {
581     // This function was declared as weak here. adc_continuous driver has one implementation.
582     // So if adc_continuous driver is not linked in, then `adc_continuous_new_handle` should be NULL at runtime.
583     extern __attribute__((weak)) esp_err_t adc_continuous_new_handle(const void *init_config, void **ret_handle);
584     if ((void *)adc_continuous_new_handle != NULL) {
585         ESP_EARLY_LOGE(ADC_TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver");
586         abort();
587     }
588     ESP_EARLY_LOGW(ADC_TAG, "legacy driver is deprecated, please migrate to `esp_adc/adc_continuous.h`");
589 }
590 
591 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
592 /*---------------------------------------------------------------
593             ADC Hardware Calibration
594 ---------------------------------------------------------------*/
adc_hw_calibration(void)595 static void adc_hw_calibration(void)
596 {
597     //Calculate all ICode
598     for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
599         adc_hal_calibration_init(i);
600         for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
601             /**
602              * This may get wrong when attenuations are NOT consecutive on some chips,
603              * update this when bringing up the calibration on that chip
604              */
605             adc_calc_hw_calibration_code(i, j);
606 #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
607             /* Load the channel compensation from efuse */
608             for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) {
609                 adc_load_hw_calibration_chan_compens(i, k, j);
610             }
611 #endif
612         }
613     }
614 }
615 #endif  //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
616