Select one of the symbols to view example projects that use it.
 
Outline
#include <sys/param.h>
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "hal/adc_hal_common.h"
#include "hal/adc_ll.h"
#include "hal/assert.h"
get_controller(adc_unit_t, adc_hal_work_mode_t)
adc_hal_set_controller(adc_unit_t, adc_hal_work_mode_t)
#include "esp_rom_sys.h"
#define ADC_HAL_CAL_TIMES
#define ADC_HAL_CAL_OFFSET_RANGE
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/hal/adc_hal_common.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */ #include <sys/param.h> #include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/adc_hal_common.h" #include "hal/adc_ll.h" #include "hal/assert.h"6 includes /*--------------------------------------------------------------- Controller Setting ---------------------------------------------------------------*//* ... */ static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) { if (unit == ADC_UNIT_1) { switch (work_mode) { #if SOC_ULP_HAS_ADC || SOC_LP_CORE_SUPPORT_LP_ADC case ADC_HAL_LP_MODE: return ADC_LL_CTRL_ULP;/* ... */ #endif case ADC_HAL_SINGLE_READ_MODE: #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED return ADC_LL_CTRL_DIG; #elif SOC_ADC_RTC_CTRL_SUPPORTED return ADC_LL_CTRL_RTC; #endif... case ADC_HAL_CONTINUOUS_READ_MODE: return ADC_LL_CTRL_DIG;... default: abort();... }{...} }{...} else { switch (work_mode) { #if SOC_ULP_HAS_ADC || SOC_LP_CORE_SUPPORT_LP_ADC case ADC_HAL_LP_MODE: return ADC_LL_CTRL_ULP;/* ... */ #endif #if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED default: return ADC_LL_CTRL_DIG;/* ... */ #else case ADC_HAL_SINGLE_READ_MODE: return ADC_LL_CTRL_RTC;... case ADC_HAL_CONTINUOUS_READ_MODE: return ADC_LL_CTRL_DIG;... case ADC_HAL_PWDET_MODE: return ADC_LL_CTRL_PWDET;... default: abort();/* ... */ #endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED/* ... */ #else default: return ADC_LL_CTRL_ARB;/* ... */ #endif }{...} }{...} }{ ... } void adc_hal_set_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) { adc_ll_controller_t ctrlr = get_controller(unit, work_mode); adc_ll_set_controller(unit, ctrlr); }{ ... } /*--------------------------------------------------------------- Arbiter ---------------------------------------------------------------*//* ... */ #if SOC_ADC_ARBITER_SUPPORTED void adc_hal_arbiter_config(adc_arbiter_t *config) { adc_ll_set_arbiter_work_mode(config->mode); adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri); }{...} /* ... */#endif // #if SOC_ADC_ARBITER_SUPPORTED /*--------------------------------------------------------------- ADC calibration setting ---------------------------------------------------------------*//* ... */ #if SOC_ADC_CALIBRATION_V1_SUPPORTED //For chips without RTC controller, Digital controller is used to trigger an ADC single read. #include "esp_rom_sys.h" void adc_hal_calibration_init(adc_unit_t adc_n) { adc_ll_calibration_init(adc_n); }{...} static uint32_t s_previous_init_code[SOC_ADC_PERIPH_NUM] = { [0 ... (SOC_ADC_PERIPH_NUM - 1)] = -1, }{...}; void adc_hal_set_calibration_param(adc_unit_t adc_n, uint32_t param) { if (param != s_previous_init_code[adc_n]) { adc_ll_set_calibration_param(adc_n, param); s_previous_init_code[adc_n] = param; }{...} }{...} #if SOC_ADC_SELF_HW_CALI_SUPPORTED static void cal_setup(adc_unit_t adc_n, adc_atten_t atten) { adc_hal_set_controller(adc_n, ADC_HAL_SINGLE_READ_MODE); adc_oneshot_ll_disable_all_unit(); // Enableinternal connect GND (for calibration). adc_oneshot_ll_disable_channel(adc_n); /** * Note: * When controlled by RTC controller, when all channels are disabled, HW auto selects channel0 atten param. * When controlled by DIG controller, unit and channel are not related to attenuation *//* ... */ adc_oneshot_ll_set_atten(adc_n, 0, atten); adc_oneshot_ll_enable(adc_n); }{...} static uint32_t read_cal_channel(adc_unit_t adc_n) { uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE; adc_oneshot_ll_clear_event(event); #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED adc_oneshot_ll_start(false); esp_rom_delay_us(5); adc_oneshot_ll_start(true);/* ... */ #else adc_oneshot_ll_start(adc_n); #endif while(!adc_oneshot_ll_get_event(event)); uint32_t read_val = -1; read_val = adc_oneshot_ll_get_raw_result(adc_n); if (adc_oneshot_ll_raw_check_valid(adc_n, read_val) == false) { return -1; }{...} return read_val; }{...} #define ADC_HAL_CAL_TIMES (10) #define ADC_HAL_CAL_OFFSET_RANGE (4096) uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_atten_t atten, bool internal_gnd) { #if SOC_ADC_ARBITER_SUPPORTED if (adc_n == ADC_UNIT_2) { adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); adc_hal_arbiter_config(&config); }{...} /* ... */#endif // #if SOC_ADC_ARBITER_SUPPORTED cal_setup(adc_n, atten); adc_ll_calibration_prepare(adc_n, internal_gnd); uint32_t code_list[ADC_HAL_CAL_TIMES] = {0}; uint32_t code_sum = 0; uint32_t code_h = 0; uint32_t code_l = 0; uint32_t chk_code = 0; for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) { code_h = ADC_HAL_CAL_OFFSET_RANGE; code_l = 0; chk_code = (code_h + code_l) / 2; adc_ll_set_calibration_param(adc_n, chk_code); uint32_t self_cal = read_cal_channel(adc_n); while (code_h - code_l > 1) { if (self_cal == 0) { code_h = chk_code; }{...} else { code_l = chk_code; }{...} chk_code = (code_h + code_l) / 2; adc_ll_set_calibration_param(adc_n, chk_code); self_cal = read_cal_channel(adc_n); if ((code_h - code_l == 1)) { chk_code += 1; adc_ll_set_calibration_param(adc_n, chk_code); self_cal = read_cal_channel(adc_n); }{...} }{...} code_list[rpt] = chk_code; code_sum += chk_code; }{...} code_l = code_list[0]; code_h = code_list[0]; for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) { code_l = MIN(code_l, code_list[i]); code_h = MAX(code_h, code_list[i]); }{...} chk_code = code_h + code_l; uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4) ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1; adc_ll_calibration_finish(adc_n); return ret; }{...} /* ... */#endif //#if SOC_ADC_SELF_HW_CALI_SUPPORTED/* ... */ #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
Details