1 /*
2  * Copyright (c) 2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT espressif_esp32_adc
8 
9 #include <errno.h>
10 #include <hal/adc_hal.h>
11 #include <hal/adc_types.h>
12 #include <esp_adc_cal.h>
13 #include <esp_heap_caps.h>
14 
15 #include <zephyr/kernel.h>
16 #include <zephyr/device.h>
17 #include <zephyr/drivers/adc.h>
18 #include "driver/periph_ctrl.h"
19 
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL);
22 
23 #if CONFIG_SOC_SERIES_ESP32
24 #define ADC_CALI_SCHEME		ESP_ADC_CAL_VAL_EFUSE_VREF
25 #define ADC_RESOLUTION_MIN	SOC_ADC_DIGI_MIN_BITWIDTH
26 #define ADC_RESOLUTION_MAX	SOC_ADC_DIGI_MAX_BITWIDTH
27 
28 /* Due to significant measurement discrepancy in higher voltage range, we
29  * clip the value instead of yet another correction. The IDF implementation
30  * for ESP32-S2 is doing it, so we copy that approach in Zephyr driver
31  */
32 #define ADC_CLIP_MVOLT_11DB	2550
33 
34 #elif CONFIG_SOC_SERIES_ESP32S2
35 #define ADC_CALI_SCHEME		ESP_ADC_CAL_VAL_EFUSE_TP
36 #define ADC_RESOLUTION_MIN	SOC_ADC_DIGI_MAX_BITWIDTH
37 #define ADC_RESOLUTION_MAX	SOC_ADC_MAX_BITWIDTH
38 
39 #elif CONFIG_SOC_SERIES_ESP32C3
40 #define ADC_CALI_SCHEME		ESP_ADC_CAL_VAL_EFUSE_TP
41 #define ADC_RESOLUTION_MIN	SOC_ADC_DIGI_MAX_BITWIDTH
42 #define ADC_RESOLUTION_MAX	SOC_ADC_DIGI_MAX_BITWIDTH
43 
44 #elif CONFIG_SOC_SERIES_ESP32S3
45 #define ADC_CALI_SCHEME		ESP_ADC_CAL_VAL_EFUSE_TP_FIT
46 #define ADC_RESOLUTION_MIN	SOC_ADC_DIGI_MIN_BITWIDTH
47 #define ADC_RESOLUTION_MAX	SOC_ADC_DIGI_MAX_BITWIDTH
48 
49 #endif
50 
51 /* Convert resolution in bits to esp32 enum values */
52 #define WIDTH_MASK(r) ((((r) - 9) < ADC_WIDTH_MAX) ? ((r) - 9) : (ADC_WIDTH_MAX - 1))
53 
54 /* Validate if resolution in bits is within allowed values */
55 #define VALID_RESOLUTION(r) ((r) >= ADC_RESOLUTION_MIN && (r) <= ADC_RESOLUTION_MAX)
56 #define INVALID_RESOLUTION(r) (!VALID_RESOLUTION(r))
57 
58 /* Default internal reference voltage */
59 #define ADC_ESP32_DEFAULT_VREF_INTERNAL (1100)
60 
61 struct adc_esp32_conf {
62 	adc_unit_t unit;
63 	uint8_t channel_count;
64 };
65 
66 struct adc_esp32_data {
67 	adc_atten_t attenuation[ADC_CHANNEL_MAX];
68 	uint8_t resolution[ADC_CHANNEL_MAX];
69 	esp_adc_cal_characteristics_t chars[ADC_CHANNEL_MAX];
70 	uint16_t meas_ref_internal;
71 	uint16_t *buffer;
72 	uint16_t *buffer_repeat;
73 	bool calibrate;
74 };
75 
76 /* Convert zephyr,gain property to the ESP32 attenuation */
gain_to_atten(enum adc_gain gain,adc_atten_t * atten)77 static inline int gain_to_atten(enum adc_gain gain, adc_atten_t *atten)
78 {
79 	switch (gain) {
80 	case ADC_GAIN_1:
81 		*atten = ADC_ATTEN_DB_0;
82 		break;
83 	case ADC_GAIN_4_5:
84 		*atten = ADC_ATTEN_DB_2_5;
85 		break;
86 	case ADC_GAIN_1_2:
87 		*atten = ADC_ATTEN_DB_6;
88 		break;
89 	case ADC_GAIN_1_4:
90 		*atten = ADC_ATTEN_DB_11;
91 		break;
92 	default:
93 		return -ENOTSUP;
94 	}
95 	return 0;
96 }
97 
98 /* Convert voltage by inverted attenuation to support zephyr gain values */
atten_to_gain(adc_atten_t atten,uint32_t * val_mv)99 static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv)
100 {
101 	if (!val_mv) {
102 		return;
103 	}
104 	switch (atten) {
105 	case ADC_ATTEN_DB_2_5:
106 		*val_mv = (*val_mv * 4) / 5; /* 1/ADC_GAIN_4_5 */
107 		break;
108 	case ADC_ATTEN_DB_6:
109 		*val_mv = *val_mv >> 1; /* 1/ADC_GAIN_1_2 */
110 		break;
111 	case ADC_ATTEN_DB_11:
112 		*val_mv = *val_mv / 4; /* 1/ADC_GAIN_1_4 */
113 		break;
114 	case ADC_ATTEN_DB_0: /* 1/ADC_GAIN_1 */
115 	default:
116 		break;
117 	}
118 }
119 
adc_calibration_init(const struct device * dev)120 static bool adc_calibration_init(const struct device *dev)
121 {
122 	struct adc_esp32_data *data = dev->data;
123 
124 	switch (esp_adc_cal_check_efuse(ADC_CALI_SCHEME)) {
125 	case ESP_ERR_NOT_SUPPORTED:
126 		LOG_WRN("Skip software calibration - Not supported!");
127 		break;
128 	case ESP_ERR_INVALID_VERSION:
129 		LOG_WRN("Skip software calibration - Invalid version!");
130 		break;
131 	case ESP_OK:
132 		LOG_DBG("Software calibration possible");
133 		return true;
134 	default:
135 		LOG_ERR("Invalid arg");
136 		break;
137 	}
138 	return false;
139 }
140 
adc_esp32_read(const struct device * dev,const struct adc_sequence * seq)141 static int adc_esp32_read(const struct device *dev, const struct adc_sequence *seq)
142 {
143 	const struct adc_esp32_conf *conf = dev->config;
144 	struct adc_esp32_data *data = dev->data;
145 	int reading;
146 	uint32_t cal, cal_mv;
147 
148 	uint8_t channel_id = find_lsb_set(seq->channels) - 1;
149 
150 	if (seq->buffer_size < 2) {
151 		LOG_ERR("Sequence buffer space too low '%d'", seq->buffer_size);
152 		return -ENOMEM;
153 	}
154 
155 	if (seq->channels > BIT(channel_id)) {
156 		LOG_ERR("Multi-channel readings not supported");
157 		return -ENOTSUP;
158 	}
159 
160 	if (seq->options) {
161 		if (seq->options->extra_samplings) {
162 			LOG_ERR("Extra samplings not supported");
163 			return -ENOTSUP;
164 		}
165 
166 		if (seq->options->interval_us) {
167 			LOG_ERR("Interval between samplings not supported");
168 			return -ENOTSUP;
169 		}
170 	}
171 
172 	if (INVALID_RESOLUTION(seq->resolution)) {
173 		LOG_ERR("unsupported resolution (%d)", seq->resolution);
174 		return -ENOTSUP;
175 	}
176 
177 	if (seq->calibrate) {
178 		/* TODO: Does this mean actual Vref measurement on selected GPIO ?*/
179 		LOG_ERR("calibration is not supported");
180 		return -ENOTSUP;
181 	}
182 
183 	data->resolution[channel_id] = seq->resolution;
184 
185 #if CONFIG_SOC_SERIES_ESP32C3
186 	/* NOTE: nothing to set on ESP32C3 SoC */
187 	if (conf->unit == ADC_UNIT_1) {
188 		adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
189 	}
190 #else
191 	adc_set_data_width(conf->unit, WIDTH_MASK(data->resolution[channel_id]));
192 #endif /* CONFIG_SOC_SERIES_ESP32C3 */
193 
194 	/* Read raw value */
195 	if (conf->unit == ADC_UNIT_1) {
196 		reading = adc1_get_raw(channel_id);
197 	}
198 	if (conf->unit == ADC_UNIT_2) {
199 		if (adc2_get_raw(channel_id, ADC_WIDTH_BIT_DEFAULT, &reading)) {
200 			LOG_ERR("Conversion timeout on '%s' channel %d", dev->name, channel_id);
201 			return -ETIMEDOUT;
202 		}
203 	}
204 
205 	/* Calibration scheme is available */
206 	if (data->calibrate) {
207 		data->chars[channel_id].bit_width = WIDTH_MASK(data->resolution[channel_id]);
208 		/* Get corrected voltage output */
209 		cal = cal_mv = esp_adc_cal_raw_to_voltage(reading, &data->chars[channel_id]);
210 
211 #if CONFIG_SOC_SERIES_ESP32
212 		if (data->attenuation[channel_id] == ADC_ATTEN_DB_11) {
213 			if (cal > ADC_CLIP_MVOLT_11DB) {
214 				cal = ADC_CLIP_MVOLT_11DB;
215 			}
216 		}
217 #endif /* CONFIG_SOC_SERIES_ESP32 */
218 
219 		/* Fit according to selected attenuation */
220 		atten_to_gain(data->attenuation[channel_id], &cal);
221 		if (data->meas_ref_internal > 0) {
222 			cal = (cal << data->resolution[channel_id]) / data->meas_ref_internal;
223 		}
224 	} else {
225 		LOG_DBG("Using uncalibrated values!");
226 		/* Uncalibrated raw value */
227 		cal = reading;
228 	}
229 
230 	/* Store result */
231 	data->buffer = (uint16_t *) seq->buffer;
232 	data->buffer[0] = cal;
233 
234 	return 0;
235 }
236 
237 #ifdef CONFIG_ADC_ASYNC
adc_esp32_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)238 static int adc_esp32_read_async(const struct device *dev,
239 				const struct adc_sequence *sequence,
240 				struct k_poll_signal *async)
241 {
242 	(void)(dev);
243 	(void)(sequence);
244 	(void)(async);
245 
246 	return -ENOTSUP;
247 }
248 #endif /* CONFIG_ADC_ASYNC */
249 
adc_esp32_channel_setup(const struct device * dev,const struct adc_channel_cfg * cfg)250 static int adc_esp32_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg)
251 {
252 	const struct adc_esp32_conf *conf = (const struct adc_esp32_conf *)dev->config;
253 	struct adc_esp32_data *data = (struct adc_esp32_data *) dev->data;
254 	int err;
255 
256 	if (cfg->channel_id >= conf->channel_count) {
257 		LOG_ERR("Unsupported channel id '%d'", cfg->channel_id);
258 		return -ENOTSUP;
259 	}
260 
261 	if (cfg->reference != ADC_REF_INTERNAL) {
262 		LOG_ERR("Unsupported channel reference '%d'", cfg->reference);
263 		return -ENOTSUP;
264 	}
265 
266 	if (cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
267 		LOG_ERR("Unsupported acquisition_time '%d'", cfg->acquisition_time);
268 		return -ENOTSUP;
269 	}
270 
271 	if (cfg->differential) {
272 		LOG_ERR("Differential channels are not supported");
273 		return -ENOTSUP;
274 	}
275 
276 	if (gain_to_atten(cfg->gain, &data->attenuation[cfg->channel_id])) {
277 		LOG_ERR("Unsupported gain value '%d'", cfg->gain);
278 		return -ENOTSUP;
279 	}
280 
281 	/* Prepare channel */
282 	if (conf->unit == ADC_UNIT_1) {
283 		adc1_config_channel_atten(cfg->channel_id, data->attenuation[cfg->channel_id]);
284 	}
285 	if (conf->unit == ADC_UNIT_2) {
286 		adc2_config_channel_atten(cfg->channel_id, data->attenuation[cfg->channel_id]);
287 	}
288 
289 	if (data->calibrate) {
290 		esp_adc_cal_value_t cal = esp_adc_cal_characterize(conf->unit,
291 						data->attenuation[cfg->channel_id],
292 						WIDTH_MASK(data->resolution[cfg->channel_id]),
293 						data->meas_ref_internal,
294 						&data->chars[cfg->channel_id]);
295 		if (cal >= ESP_ADC_CAL_VAL_NOT_SUPPORTED) {
296 			LOG_ERR("Calibration error or not supported");
297 			return -EIO;
298 		}
299 		LOG_DBG("Using ADC calibration method %d", cal);
300 	}
301 
302 	return 0;
303 }
304 
adc_esp32_init(const struct device * dev)305 static int adc_esp32_init(const struct device *dev)
306 {
307 	struct adc_esp32_data *data = (struct adc_esp32_data *) dev->data;
308 
309 	for (uint8_t i = 0; i < ARRAY_SIZE(data->resolution); i++) {
310 		data->resolution[i] = ADC_RESOLUTION_MAX;
311 	}
312 	for (uint8_t i = 0; i < ARRAY_SIZE(data->attenuation); i++) {
313 		data->attenuation[i] = ADC_ATTEN_DB_0;
314 	}
315 
316 	/* Default reference voltage. This could be calibrated externaly */
317 	data->meas_ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL;
318 
319 	/* Check if calibration is possible */
320 	data->calibrate = adc_calibration_init(dev);
321 
322 	return 0;
323 }
324 
325 static const struct adc_driver_api api_esp32_driver_api = {
326 	.channel_setup = adc_esp32_channel_setup,
327 	.read          = adc_esp32_read,
328 #ifdef CONFIG_ADC_ASYNC
329 	.read_async    = adc_esp32_read_async,
330 #endif /* CONFIG_ADC_ASYNC */
331 	.ref_internal  = ADC_ESP32_DEFAULT_VREF_INTERNAL,
332 };
333 
334 #define ESP32_ADC_INIT(inst)							\
335 										\
336 	static const struct adc_esp32_conf adc_esp32_conf_##inst = {		\
337 		.unit = DT_PROP(DT_DRV_INST(inst), unit),			\
338 		.channel_count = DT_PROP(DT_DRV_INST(inst), channel_count),	\
339 	};									\
340 										\
341 	static struct adc_esp32_data adc_esp32_data_##inst = {			\
342 	};									\
343 										\
344 DEVICE_DT_INST_DEFINE(inst, &adc_esp32_init, NULL,				\
345 		&adc_esp32_data_##inst,						\
346 		&adc_esp32_conf_##inst,						\
347 		POST_KERNEL,							\
348 		CONFIG_ADC_INIT_PRIORITY,					\
349 		&api_esp32_driver_api);
350 
351 DT_INST_FOREACH_STATUS_OKAY(ESP32_ADC_INIT)
352