1 /*
2 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <sys/param.h>
8 #include "sdkconfig.h"
9 #include "hal/adc_hal.h"
10 #include "hal/adc_hal_conf.h"
11 #include "hal/assert.h"
12 #include "soc/lldesc.h"
13 #include "soc/soc_caps.h"
14
15 #if CONFIG_IDF_TARGET_ESP32
16 //ADC utilises I2S0 DMA on ESP32
17 #include "hal/i2s_ll.h"
18 #include "hal/i2s_types.h"
19 #include "soc/i2s_struct.h"
20 #endif
21
22 #if CONFIG_IDF_TARGET_ESP32S2
23 //ADC utilises SPI3 DMA on ESP32S2
24 #include "hal/spi_ll.h"
25 #include "soc/spi_struct.h"
26 #endif
27
28 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
29 /*---------------------------------------------------------------
30 Single Read
31 ---------------------------------------------------------------*/
32 /**
33 * For chips without RTC controller, Digital controller is used to trigger an ADC single read.
34 */
35 #include "esp_rom_sys.h"
36
37 typedef enum {
38 ADC_EVENT_ADC1_DONE = BIT(0),
39 ADC_EVENT_ADC2_DONE = BIT(1),
40 } adc_hal_event_t;
41 #endif //SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
42
43 /*---------------------------------------------------------------
44 Define all ADC DMA required operations here
45 ---------------------------------------------------------------*/
46 #if SOC_GDMA_SUPPORTED
47 #define adc_dma_ll_rx_clear_intr(dev, chan, mask) gdma_ll_rx_clear_interrupt_status(dev, chan, mask)
48 #define adc_dma_ll_rx_enable_intr(dev, chan, mask) gdma_ll_rx_enable_interrupt(dev, chan, mask, true)
49 #define adc_dma_ll_rx_disable_intr(dev, chan, mask) gdma_ll_rx_enable_interrupt(dev, chan, mask, false)
50 #define adc_dma_ll_rx_reset_channel(dev, chan) gdma_ll_rx_reset_channel(dev, chan)
51 #define adc_dma_ll_rx_stop(dev, chan) gdma_ll_rx_stop(dev, chan)
52 #define adc_dma_ll_rx_start(dev, chan, addr) do { \
53 gdma_ll_rx_set_desc_addr(dev, chan, (uint32_t)addr); \
54 gdma_ll_rx_start(dev, chan); \
55 } while (0)
56 #define adc_ll_digi_dma_set_eof_num(dev, num) adc_ll_digi_dma_set_eof_num(num)
57 #define adc_ll_digi_reset(dev) adc_ll_digi_reset()
58 #define adc_ll_digi_trigger_enable(dev) adc_ll_digi_trigger_enable()
59 #define adc_ll_digi_trigger_disable(dev) adc_ll_digi_trigger_disable()
60
61 //ADC utilises SPI3 DMA on ESP32S2
62 #elif CONFIG_IDF_TARGET_ESP32S2
63 #define adc_dma_ll_rx_get_intr(dev, mask) spi_ll_get_intr(dev, mask)
64 #define adc_dma_ll_rx_clear_intr(dev, chan, mask) spi_ll_clear_intr(dev, mask)
65 #define adc_dma_ll_rx_enable_intr(dev, chan, mask) spi_ll_enable_intr(dev, mask)
66 #define adc_dma_ll_rx_disable_intr(dev, chan, mask) spi_ll_disable_intr(dev, mask)
67 #define adc_dma_ll_rx_reset_channel(dev, chan) spi_dma_ll_rx_reset(dev, chan)
68 #define adc_dma_ll_rx_stop(dev, chan) spi_dma_ll_rx_stop(dev, chan)
69 #define adc_dma_ll_rx_start(dev, chan, addr) spi_dma_ll_rx_start(dev, chan, addr)
70 #define adc_dma_ll_get_in_suc_eof_desc_addr(dev, chan) spi_dma_ll_get_in_suc_eof_desc_addr(dev, chan)
71 #define adc_ll_digi_dma_set_eof_num(dev, num) adc_ll_digi_dma_set_eof_num(num)
72 #define adc_ll_digi_reset(dev) adc_ll_digi_reset()
73 #define adc_ll_digi_trigger_enable(dev) adc_ll_digi_trigger_enable()
74 #define adc_ll_digi_trigger_disable(dev) adc_ll_digi_trigger_disable()
75
76 //ADC utilises I2S0 DMA on ESP32
77 #else //CONFIG_IDF_TARGET_ESP32
78 #define adc_dma_ll_rx_get_intr(dev, mask) ({i2s_ll_get_intr_status(dev) & mask;})
79 #define adc_dma_ll_rx_clear_intr(dev, chan, mask) i2s_ll_clear_intr_status(dev, mask)
80 #define adc_dma_ll_rx_enable_intr(dev, chan, mask) do {((i2s_dev_t *)(dev))->int_ena.val |= mask;} while (0)
81 #define adc_dma_ll_rx_disable_intr(dev, chan, mask) do {((i2s_dev_t *)(dev))->int_ena.val &= ~mask;} while (0)
82 #define adc_dma_ll_rx_reset_channel(dev, chan) i2s_ll_rx_reset_dma(dev)
83 #define adc_dma_ll_rx_stop(dev, chan) i2s_ll_rx_stop_link(dev)
84 #define adc_dma_ll_rx_start(dev, chan, address) do { \
85 ((i2s_dev_t *)(dev))->in_link.addr = (uint32_t)(address); \
86 i2s_ll_enable_dma(dev, 1); \
87 ((i2s_dev_t *)(dev))->in_link.start = 1; \
88 } while (0)
89 #define adc_dma_ll_get_in_suc_eof_desc_addr(dev, chan) ({uint32_t addr; i2s_ll_rx_get_eof_des_addr(dev, &addr); addr;})
90 #define adc_ll_digi_dma_set_eof_num(dev, num) do {((i2s_dev_t *)(dev))->rx_eof_num = num;} while (0)
91 #define adc_ll_digi_reset(dev) do { \
92 i2s_ll_rx_reset(dev); \
93 i2s_ll_rx_reset_fifo(dev); \
94 } while (0)
95 #define adc_ll_digi_trigger_enable(dev) i2s_ll_rx_start(dev)
96 #define adc_ll_digi_trigger_disable(dev) i2s_ll_rx_stop(dev)
97 #define adc_ll_digi_dma_enable() adc_ll_digi_set_data_source(1) //Will this influence I2S0
98 #define adc_ll_digi_dma_disable() adc_ll_digi_set_data_source(0)
99
100 //ESP32 ADC uses the DMA through I2S. The I2S needs to be configured.
101 #define I2S_BASE_CLK (2*APB_CLK_FREQ)
102 #define SAMPLE_BITS 16
103 #define ADC_LL_CLKM_DIV_NUM_DEFAULT 2
104 #define ADC_LL_CLKM_DIV_B_DEFAULT 0
105 #define ADC_LL_CLKM_DIV_A_DEFAULT 1
106
107 #endif
108
109
adc_hal_init(void)110 void adc_hal_init(void)
111 {
112 // Set internal FSM wait time, fixed value.
113 adc_ll_digi_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT,
114 SOC_ADC_FSM_STANDBY_WAIT_DEFAULT);
115 adc_ll_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT);
116 adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
117 adc_ll_digi_output_invert(ADC_NUM_1, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_1));
118 adc_ll_digi_output_invert(ADC_NUM_2, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_2));
119 adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT);
120 }
121
122 #if SOC_ADC_ARBITER_SUPPORTED
adc_hal_arbiter_config(adc_arbiter_t * config)123 void adc_hal_arbiter_config(adc_arbiter_t *config)
124 {
125 adc_ll_set_arbiter_work_mode(config->mode);
126 adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
127 }
128 #endif // #if SOC_ADC_ARBITER_SUPPORTED
129
adc_hal_digi_deinit(adc_hal_context_t * hal)130 void adc_hal_digi_deinit(adc_hal_context_t *hal)
131 {
132 adc_ll_digi_trigger_disable(hal->dev);
133 adc_ll_digi_dma_disable();
134 adc_ll_digi_clear_pattern_table(ADC_NUM_1);
135 adc_ll_digi_clear_pattern_table(ADC_NUM_2);
136 adc_ll_digi_reset(hal->dev);
137 adc_ll_digi_controller_clk_disable();
138 }
139
140 /*---------------------------------------------------------------
141 Controller Setting
142 ---------------------------------------------------------------*/
get_controller(adc_ll_num_t unit,adc_hal_work_mode_t work_mode)143 static adc_ll_controller_t get_controller(adc_ll_num_t unit, adc_hal_work_mode_t work_mode)
144 {
145 if (unit == ADC_NUM_1) {
146 switch (work_mode) {
147 #if SOC_ULP_SUPPORTED
148 case ADC_HAL_ULP_MODE:
149 return ADC_LL_CTRL_ULP;
150 #endif
151 case ADC_HAL_SINGLE_READ_MODE:
152 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
153 return ADC_LL_CTRL_DIG;
154 #elif SOC_ADC_RTC_CTRL_SUPPORTED
155 return ADC_LL_CTRL_RTC;
156 #endif
157 case ADC_HAL_CONTINUOUS_READ_MODE:
158 return ADC_LL_CTRL_DIG;
159 default:
160 abort();
161 }
162 } else {
163 switch (work_mode) {
164 #if SOC_ULP_SUPPORTED
165 case ADC_HAL_ULP_MODE:
166 return ADC_LL_CTRL_ULP;
167 #endif
168 #if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32
169 case ADC_HAL_SINGLE_READ_MODE:
170 return ADC_LL_CTRL_RTC;
171 case ADC_HAL_CONTINUOUS_READ_MODE:
172 return ADC_LL_CTRL_DIG;
173 case ADC_HAL_PWDET_MODE:
174 return ADC_LL_CTRL_PWDET;
175 default:
176 abort();
177 #else
178 default:
179 return ADC_LL_CTRL_ARB;
180 #endif
181 }
182 }
183 return (adc_ll_controller_t) 0; /* make compiler happy */
184 }
185
adc_hal_set_controller(adc_ll_num_t unit,adc_hal_work_mode_t work_mode)186 void adc_hal_set_controller(adc_ll_num_t unit, adc_hal_work_mode_t work_mode)
187 {
188 adc_ll_controller_t ctrlr = get_controller(unit, work_mode);
189 adc_ll_set_controller(unit, ctrlr);
190 }
191
192 /*---------------------------------------------------------------
193 DMA read
194 ---------------------------------------------------------------*/
get_convert_mode(adc_digi_convert_mode_t convert_mode)195 static adc_ll_digi_convert_mode_t get_convert_mode(adc_digi_convert_mode_t convert_mode)
196 {
197 #if CONFIG_IDF_TARGET_ESP32
198 return ADC_LL_DIGI_CONV_ONLY_ADC1;
199 #endif
200 #if (SOC_ADC_DIGI_CONTROLLER_NUM == 1)
201 return ADC_LL_DIGI_CONV_ALTER_UNIT;
202 #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2)
203 switch (convert_mode) {
204 case ADC_CONV_SINGLE_UNIT_1:
205 return ADC_LL_DIGI_CONV_ONLY_ADC1;
206 case ADC_CONV_SINGLE_UNIT_2:
207 return ADC_LL_DIGI_CONV_ONLY_ADC2;
208 case ADC_CONV_BOTH_UNIT:
209 return ADC_LL_DIGI_CONV_BOTH_UNIT;
210 case ADC_CONV_ALTER_UNIT:
211 return ADC_LL_DIGI_CONV_ALTER_UNIT;
212 default:
213 abort();
214 }
215 #endif
216 return (adc_ll_digi_convert_mode_t) 0; /* make compiler happy */
217 }
218
219 /**
220 * For esp32s2 and later chips
221 * - Set ADC digital controller clock division factor. The clock is divided from `APLL` or `APB` clock.
222 * Expression: controller_clk = APLL/APB * (div_num + div_a / div_b + 1).
223 * - Enable clock and select clock source for ADC digital controller.
224 * For esp32, use I2S clock
225 */
adc_hal_digi_sample_freq_config(adc_hal_context_t * hal,uint32_t freq)226 static void adc_hal_digi_sample_freq_config(adc_hal_context_t *hal, uint32_t freq)
227 {
228 #if !CONFIG_IDF_TARGET_ESP32
229 uint32_t interval = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1) / 2 / freq;
230 //set sample interval
231 adc_ll_digi_set_trigger_interval(interval);
232 //Here we set the clock divider factor to make the digital clock to 5M Hz
233 adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT);
234 adc_ll_digi_clk_sel(0); //use APB
235 #else
236 i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_D2CLK); /*!< Clock from PLL_D2_CLK(160M)*/
237 uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq;
238 i2s_ll_mclk_div_t clk = {
239 .mclk_div = ADC_LL_CLKM_DIV_NUM_DEFAULT,
240 .a = ADC_LL_CLKM_DIV_A_DEFAULT,
241 .b = ADC_LL_CLKM_DIV_B_DEFAULT,
242 };
243 i2s_ll_rx_set_clk(hal->dev, &clk);
244 i2s_ll_rx_set_bck_div_num(hal->dev, bck);
245 #endif
246 }
247
adc_hal_digi_controller_config(adc_hal_context_t * hal,const adc_hal_digi_ctrlr_cfg_t * cfg)248 void adc_hal_digi_controller_config(adc_hal_context_t *hal, const adc_hal_digi_ctrlr_cfg_t *cfg)
249 {
250 #if (SOC_ADC_DIGI_CONTROLLER_NUM == 1)
251 //Only one pattern table, this variable is for readability
252 const int pattern_both = 0;
253
254 adc_ll_digi_clear_pattern_table(pattern_both);
255 adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
256 for (int i = 0; i < cfg->adc_pattern_len; i++) {
257 adc_ll_digi_set_pattern_table(pattern_both, i, cfg->adc_pattern[i]);
258 }
259
260 #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2)
261 uint32_t adc1_pattern_idx = 0;
262 uint32_t adc2_pattern_idx = 0;
263
264 adc_ll_digi_clear_pattern_table(ADC_NUM_1);
265 adc_ll_digi_clear_pattern_table(ADC_NUM_2);
266
267 for (int i = 0; i < cfg->adc_pattern_len; i++) {
268 if (cfg->adc_pattern[i].unit == ADC_NUM_1) {
269 adc_ll_digi_set_pattern_table(ADC_NUM_1, adc1_pattern_idx, cfg->adc_pattern[i]);
270 adc1_pattern_idx++;
271 } else if (cfg->adc_pattern[i].unit == ADC_NUM_2) {
272 adc_ll_digi_set_pattern_table(ADC_NUM_2, adc2_pattern_idx, cfg->adc_pattern[i]);
273 adc2_pattern_idx++;
274 } else {
275 abort();
276 }
277 }
278 adc_ll_digi_set_pattern_table_len(ADC_NUM_1, adc1_pattern_idx);
279 adc_ll_digi_set_pattern_table_len(ADC_NUM_2, adc2_pattern_idx);
280
281 #endif
282
283 if (cfg->conv_limit_en) {
284 adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
285 adc_ll_digi_convert_limit_enable();
286 } else {
287 adc_ll_digi_convert_limit_disable();
288 }
289
290 adc_ll_digi_set_convert_mode(get_convert_mode(cfg->conv_mode));
291
292 //clock and sample frequency
293 adc_hal_digi_sample_freq_config(hal, cfg->sample_freq_hz);
294 }
295
adc_hal_context_config(adc_hal_context_t * hal,const adc_hal_config_t * config)296 void adc_hal_context_config(adc_hal_context_t *hal, const adc_hal_config_t *config)
297 {
298 hal->desc_dummy_head.next = hal->rx_desc;
299 hal->dev = config->dev;
300 hal->desc_max_num = config->desc_max_num;
301 hal->dma_chan = config->dma_chan;
302 hal->eof_num = config->eof_num;
303 }
304
adc_hal_digi_init(adc_hal_context_t * hal)305 void adc_hal_digi_init(adc_hal_context_t *hal)
306 {
307 adc_dma_ll_rx_clear_intr(hal->dev, hal->dma_chan, ADC_HAL_DMA_INTR_MASK);
308 adc_dma_ll_rx_enable_intr(hal->dev, hal->dma_chan, ADC_HAL_DMA_INTR_MASK);
309 adc_ll_digi_dma_set_eof_num(hal->dev, hal->eof_num);
310 #if CONFIG_IDF_TARGET_ESP32
311 i2s_ll_rx_set_sample_bit(hal->dev, SAMPLE_BITS, SAMPLE_BITS);
312 i2s_ll_rx_enable_mono_mode(hal->dev, 1);
313 i2s_ll_rx_force_enable_fifo_mod(hal->dev, 1);
314 i2s_ll_enable_builtin_adc(hal->dev, 1);
315 #endif
316 #if CONFIG_IDF_TARGET_ESP32C3
317 adc_ll_onetime_sample_enable(ADC_NUM_1, false);
318 adc_ll_onetime_sample_enable(ADC_NUM_2, false);
319 #endif
320 }
321
adc_hal_digi_dma_link_descriptors(dma_descriptor_t * desc,uint8_t * data_buf,uint32_t size,uint32_t num)322 static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t size, uint32_t num)
323 {
324 HAL_ASSERT(((uint32_t)data_buf % 4) == 0);
325 HAL_ASSERT((size % 4) == 0);
326 uint32_t n = 0;
327
328 while (num--) {
329 desc[n] = (dma_descriptor_t) {
330 .dw0.size = size,
331 .dw0.length = 0,
332 .dw0.suc_eof = 0,
333 .dw0.owner = 1,
334 .buffer = data_buf,
335 .next = &desc[n+1]
336 };
337 data_buf += size;
338 n++;
339 }
340 desc[n-1].next = NULL;
341 }
342
adc_hal_digi_start(adc_hal_context_t * hal,uint8_t * data_buf)343 void adc_hal_digi_start(adc_hal_context_t *hal, uint8_t *data_buf)
344 {
345 //stop peripheral and DMA
346 adc_hal_digi_stop(hal);
347
348 //reset DMA
349 adc_dma_ll_rx_reset_channel(hal->dev, hal->dma_chan);
350 //reset peripheral
351 adc_ll_digi_reset(hal->dev);
352
353 //reset the current descriptor address
354 hal->cur_desc_ptr = &hal->desc_dummy_head;
355 adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * ADC_HAL_DATA_LEN_PER_CONV, hal->desc_max_num);
356
357 //start DMA
358 adc_dma_ll_rx_start(hal->dev, hal->dma_chan, (lldesc_t *)hal->rx_desc);
359 //connect DMA and peripheral
360 adc_ll_digi_dma_enable();
361 //start ADC
362 adc_ll_digi_trigger_enable(hal->dev);
363 }
364
365 #if !SOC_GDMA_SUPPORTED
adc_hal_get_desc_addr(adc_hal_context_t * hal)366 intptr_t adc_hal_get_desc_addr(adc_hal_context_t *hal)
367 {
368 return adc_dma_ll_get_in_suc_eof_desc_addr(hal->dev, hal->dma_chan);
369 }
370
adc_hal_check_event(adc_hal_context_t * hal,uint32_t mask)371 bool adc_hal_check_event(adc_hal_context_t *hal, uint32_t mask)
372 {
373 return adc_dma_ll_rx_get_intr(hal->dev, mask);
374 }
375 #endif //#if !SOC_GDMA_SUPPORTED
376
adc_hal_get_reading_result(adc_hal_context_t * hal,const intptr_t eof_desc_addr,dma_descriptor_t ** cur_desc)377 adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, dma_descriptor_t **cur_desc)
378 {
379 HAL_ASSERT(hal->cur_desc_ptr);
380 if (!hal->cur_desc_ptr->next) {
381 return ADC_HAL_DMA_DESC_NULL;
382 }
383 if ((intptr_t)hal->cur_desc_ptr == eof_desc_addr) {
384 return ADC_HAL_DMA_DESC_WAITING;
385 }
386
387 hal->cur_desc_ptr = hal->cur_desc_ptr->next;
388 *cur_desc = hal->cur_desc_ptr;
389
390 return ADC_HAL_DMA_DESC_VALID;
391 }
392
adc_hal_digi_clr_intr(adc_hal_context_t * hal,uint32_t mask)393 void adc_hal_digi_clr_intr(adc_hal_context_t *hal, uint32_t mask)
394 {
395 adc_dma_ll_rx_clear_intr(hal->dev, hal->dma_chan, mask);
396 }
397
adc_hal_digi_dis_intr(adc_hal_context_t * hal,uint32_t mask)398 void adc_hal_digi_dis_intr(adc_hal_context_t *hal, uint32_t mask)
399 {
400 adc_dma_ll_rx_disable_intr(hal->dev, hal->dma_chan, mask);
401 }
402
adc_hal_digi_stop(adc_hal_context_t * hal)403 void adc_hal_digi_stop(adc_hal_context_t *hal)
404 {
405 //stop ADC
406 adc_ll_digi_trigger_disable(hal->dev);
407 //stop DMA
408 adc_dma_ll_rx_stop(hal->dev, hal->dma_chan);
409 //disconnect DMA and peripheral
410 adc_ll_digi_dma_disable();
411 }
412
413 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
414 /*---------------------------------------------------------------
415 Single Read
416 ---------------------------------------------------------------*/
417 /**
418 * For chips without RTC controller, Digital controller is used to trigger an ADC single read.
419 */
420
421 //--------------------INTR-------------------------------//
get_event_intr(adc_hal_event_t event)422 static adc_ll_intr_t get_event_intr(adc_hal_event_t event)
423 {
424 adc_ll_intr_t intr_mask = 0;
425 if (event & ADC_EVENT_ADC1_DONE) {
426 intr_mask |= ADC_LL_INTR_ADC1_DONE;
427 }
428 if (event & ADC_EVENT_ADC2_DONE) {
429 intr_mask |= ADC_LL_INTR_ADC2_DONE;
430 }
431 return intr_mask;
432 }
433
adc_hal_intr_clear(adc_hal_event_t event)434 static void adc_hal_intr_clear(adc_hal_event_t event)
435 {
436 adc_ll_intr_clear(get_event_intr(event));
437 }
438
adc_hal_intr_get_raw(adc_hal_event_t event)439 static bool adc_hal_intr_get_raw(adc_hal_event_t event)
440 {
441 return adc_ll_intr_get_raw(get_event_intr(event));
442 }
443
444
445 //--------------------Single Read-------------------------------//
adc_hal_onetime_start(void)446 static void adc_hal_onetime_start(void)
447 {
448 /**
449 * There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the
450 * ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller
451 * clock cycle.
452 *
453 * This limitation will be removed in hardware future versions.
454 *
455 */
456 uint32_t digi_clk = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1);
457 //Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough.
458 uint32_t delay = (1000 * 1000) / digi_clk + 1;
459 //3 ADC digital controller clock cycle
460 delay = delay * 3;
461 //This coefficient (8) is got from test. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed.
462 if (digi_clk >= APB_CLK_FREQ/8) {
463 delay = 0;
464 }
465
466 adc_ll_onetime_start(false);
467 esp_rom_delay_us(delay);
468 adc_ll_onetime_start(true);
469
470 //No need to delay here. Becuase if the start signal is not seen, there won't be a done intr.
471 }
472
adc_hal_single_read(adc_ll_num_t adc_n,int * out_raw)473 static esp_err_t adc_hal_single_read(adc_ll_num_t adc_n, int *out_raw)
474 {
475 if (adc_n == ADC_NUM_1) {
476 *out_raw = adc_ll_adc1_read();
477 } else if (adc_n == ADC_NUM_2) {
478 *out_raw = adc_ll_adc2_read();
479 if (adc_ll_analysis_raw_data(adc_n, *out_raw)) {
480 return ESP_ERR_INVALID_STATE;
481 }
482 }
483 return ESP_OK;
484 }
485
adc_hal_convert(adc_ll_num_t adc_n,int channel,int * out_raw)486 esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw)
487 {
488 esp_err_t ret;
489 adc_hal_event_t event;
490
491 if (adc_n == ADC_NUM_1) {
492 event = ADC_EVENT_ADC1_DONE;
493 } else {
494 event = ADC_EVENT_ADC2_DONE;
495 }
496
497 adc_hal_intr_clear(event);
498 adc_ll_onetime_sample_enable(ADC_NUM_1, false);
499 adc_ll_onetime_sample_enable(ADC_NUM_2, false);
500 adc_ll_onetime_sample_enable(adc_n, true);
501 adc_ll_onetime_set_channel(adc_n, channel);
502
503 //Trigger single read.
504 adc_hal_onetime_start();
505 while (!adc_hal_intr_get_raw(event));
506 ret = adc_hal_single_read(adc_n, out_raw);
507 //HW workaround: when enabling periph clock, this should be false
508 adc_ll_onetime_sample_enable(adc_n, false);
509
510 return ret;
511 }
512
513 #else // #if SOC_ADC_RTC_CTRL_SUPPORTED
adc_hal_convert(adc_ll_num_t adc_n,int channel,int * out_raw)514 esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw)
515 {
516 adc_ll_rtc_enable_channel(adc_n, channel);
517 adc_ll_rtc_start_convert(adc_n, channel);
518 while (adc_ll_rtc_convert_is_done(adc_n) != true);
519 *out_raw = adc_ll_rtc_get_convert_value(adc_n);
520
521 if ((int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*out_raw))) {
522 return ESP_ERR_INVALID_STATE;
523 }
524
525 return ESP_OK;
526 }
527 #endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
528
529
530 /*---------------------------------------------------------------
531 ADC calibration setting
532 ---------------------------------------------------------------*/
533 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_hal_calibration_init(adc_ll_num_t adc_n)534 void adc_hal_calibration_init(adc_ll_num_t adc_n)
535 {
536 adc_ll_calibration_init(adc_n);
537 }
538
539 static uint32_t s_previous_init_code[SOC_ADC_PERIPH_NUM] = {-1, -1};
540
adc_hal_set_calibration_param(adc_ll_num_t adc_n,uint32_t param)541 void adc_hal_set_calibration_param(adc_ll_num_t adc_n, uint32_t param)
542 {
543 if (param != s_previous_init_code[adc_n]) {
544 adc_ll_set_calibration_param(adc_n, param);
545 s_previous_init_code[adc_n] = param;
546 }
547 }
548
549 #if SOC_ADC_RTC_CTRL_SUPPORTED
cal_setup(adc_ll_num_t adc_n,adc_channel_t channel,adc_atten_t atten,bool internal_gnd)550 static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
551 {
552 adc_hal_set_controller(adc_n, ADC_HAL_SINGLE_READ_MODE); //Set controller
553
554 /* Enable/disable internal connect GND (for calibration). */
555 if (internal_gnd) {
556 adc_ll_rtc_disable_channel(adc_n);
557 adc_ll_set_atten(adc_n, 0, atten); // Note: when disable all channel, HW auto select channel0 atten param.
558 } else {
559 adc_ll_rtc_enable_channel(adc_n, channel);
560 adc_ll_set_atten(adc_n, channel, atten);
561 }
562 }
563
read_cal_channel(adc_ll_num_t adc_n,int channel)564 static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
565 {
566 adc_ll_rtc_start_convert(adc_n, channel);
567 while (adc_ll_rtc_convert_is_done(adc_n) != true);
568 return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
569 }
570
571 //For those RTC controller not supported chips, they use digital controller to do the single read. e.g.: esp32c3
572 #elif SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
cal_setup(adc_ll_num_t adc_n,adc_channel_t channel,adc_atten_t atten,bool internal_gnd)573 static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
574 {
575 adc_ll_onetime_sample_enable(ADC_NUM_1, false);
576 adc_ll_onetime_sample_enable(ADC_NUM_2, false);
577 /* Enable/disable internal connect GND (for calibration). */
578 if (internal_gnd) {
579 const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1)? 0xF: 0x1;
580 adc_ll_onetime_set_channel(adc_n, esp32c3_invalid_chan);
581 } else {
582 adc_ll_onetime_set_channel(adc_n, channel);
583 }
584 adc_ll_onetime_set_atten(atten);
585 adc_ll_onetime_sample_enable(adc_n, true);
586 }
587
read_cal_channel(adc_ll_num_t adc_n,int channel)588 static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
589 {
590 adc_ll_intr_clear(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE);
591 adc_ll_onetime_start(false);
592 esp_rom_delay_us(5);
593 adc_ll_onetime_start(true);
594
595 while(!adc_ll_intr_get_raw(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE));
596
597 uint32_t read_val = -1;
598 if (adc_n == ADC_NUM_1) {
599 read_val = adc_ll_adc1_read();
600 } else if (adc_n == ADC_NUM_2) {
601 read_val = adc_ll_adc2_read();
602 if (adc_ll_analysis_raw_data(adc_n, read_val)) {
603 return -1;
604 }
605 }
606 return read_val;
607 }
608 #endif //Do single read via DIGI controller or RTC controller
609
610 #define ADC_HAL_CAL_TIMES (10)
611 #define ADC_HAL_CAL_OFFSET_RANGE (4096)
612
adc_hal_self_calibration(adc_ll_num_t adc_n,adc_channel_t channel,adc_atten_t atten,bool internal_gnd)613 uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
614 {
615 if (adc_n == ADC_NUM_2) {
616 adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
617 adc_hal_arbiter_config(&config);
618 }
619
620 cal_setup(adc_n, channel, atten, internal_gnd);
621
622 adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
623
624 uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
625 uint32_t code_sum = 0;
626 uint32_t code_h = 0;
627 uint32_t code_l = 0;
628 uint32_t chk_code = 0;
629
630 for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
631 code_h = ADC_HAL_CAL_OFFSET_RANGE;
632 code_l = 0;
633 chk_code = (code_h + code_l) / 2;
634 adc_ll_set_calibration_param(adc_n, chk_code);
635 uint32_t self_cal = read_cal_channel(adc_n, channel);
636 while (code_h - code_l > 1) {
637 if (self_cal == 0) {
638 code_h = chk_code;
639 } else {
640 code_l = chk_code;
641 }
642 chk_code = (code_h + code_l) / 2;
643 adc_ll_set_calibration_param(adc_n, chk_code);
644 self_cal = read_cal_channel(adc_n, channel);
645 if ((code_h - code_l == 1)) {
646 chk_code += 1;
647 adc_ll_set_calibration_param(adc_n, chk_code);
648 self_cal = read_cal_channel(adc_n, channel);
649 }
650 }
651 code_list[rpt] = chk_code;
652 code_sum += chk_code;
653 }
654
655 code_l = code_list[0];
656 code_h = code_list[0];
657 for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
658 code_l = MIN(code_l, code_list[i]);
659 code_h = MAX(code_h, code_list[i]);
660 }
661
662 chk_code = code_h + code_l;
663 uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
664 ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
665 : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
666
667 adc_ll_calibration_finish(adc_n);
668 return ret;
669 }
670 #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
671