Skip to content

Commit 7127757

Browse files
wmrsouzakartben
authored andcommitted
driver: adc: esp32: fix read function
Compensates raw value reading before adc_read returns it Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
1 parent 355143b commit 7127757

File tree

1 file changed

+62
-8
lines changed

1 file changed

+62
-8
lines changed

drivers/adc/adc_esp32.c

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL);
4545

4646
#define ADC_DMA_BUFFER_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED
4747

48+
#define ADC_CLIP_MVOLT_12DB 2550
49+
4850
struct adc_esp32_conf {
4951
const struct device *clock_dev;
5052
const clock_control_subsys_t clock_subsys;
@@ -93,6 +95,42 @@ static inline int gain_to_atten(enum adc_gain gain, adc_atten_t *atten)
9395
return 0;
9496
}
9597

98+
#if !defined(CONFIG_ADC_ESP32_DMA)
99+
100+
/* Convert voltage by inverted attenuation to support zephyr gain values */
101+
static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv)
102+
{
103+
uint32_t num, den;
104+
105+
if (!val_mv) {
106+
return;
107+
}
108+
109+
switch (atten) {
110+
case ADC_ATTEN_DB_2_5: /* 1/ADC_GAIN_4_5 */
111+
num = 4;
112+
den = 5;
113+
break;
114+
case ADC_ATTEN_DB_6: /* 1/ADC_GAIN_1_2 */
115+
num = 1;
116+
den = 2;
117+
break;
118+
case ADC_ATTEN_DB_12: /* 1/ADC_GAIN_1_4 */
119+
num = 1;
120+
den = 4;
121+
break;
122+
case ADC_ATTEN_DB_0: /* 1/ADC_GAIN_1 */
123+
default:
124+
num = 1;
125+
den = 1;
126+
break;
127+
}
128+
129+
*val_mv = (*val_mv * num) / den;
130+
}
131+
132+
#endif /* !defined(CONFIG_ADC_ESP32_DMA) */
133+
96134
static void adc_hw_calibration(adc_unit_t unit)
97135
{
98136
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
@@ -375,7 +413,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s
375413

376414
#if !defined(CONFIG_ADC_ESP32_DMA)
377415

378-
uint32_t acq_raw, acq_mv, result;
416+
uint32_t acq_raw;
379417

380418
adc_oneshot_hal_setup(&data->hal, channel_id);
381419

@@ -386,20 +424,36 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s
386424
adc_oneshot_hal_convert(&data->hal, &acq_raw);
387425

388426
if (data->cal_handle[channel_id]) {
389-
adc_cali_raw_to_voltage(data->cal_handle[channel_id], acq_raw, &acq_mv);
427+
if (data->meas_ref_internal > 0) {
428+
uint32_t acq_mv;
390429

391-
LOG_DBG("ADC acquisition [unit: %u, chan: %u, acq_raw: %u, acq_mv: %u]",
392-
data->hal.unit, channel_id, acq_raw, acq_mv);
430+
adc_cali_raw_to_voltage(data->cal_handle[channel_id], acq_raw, &acq_mv);
393431

394-
result = acq_mv;
432+
LOG_DBG("ADC acquisition [unit: %u, chan: %u, acq_raw: %u, acq_mv: %u]",
433+
data->hal.unit, channel_id, acq_raw, acq_mv);
434+
435+
#if CONFIG_SOC_SERIES_ESP32
436+
if (data->attenuation[channel_id] == ADC_ATTEN_DB_12) {
437+
if (acq_mv > ADC_CLIP_MVOLT_12DB) {
438+
acq_mv = ADC_CLIP_MVOLT_12DB;
439+
}
440+
}
441+
#endif /* CONFIG_SOC_SERIES_ESP32 */
442+
443+
/* Fit according to selected attenuation */
444+
atten_to_gain(data->attenuation[channel_id], &acq_mv);
445+
acq_raw = acq_mv * ((1 << data->resolution[channel_id]) - 1) /
446+
data->meas_ref_internal;
447+
} else {
448+
LOG_WRN("ADC reading is uncompensated");
449+
}
395450
} else {
396-
LOG_WRN("ADC values are raw (uncalibrated)");
397-
result = acq_raw;
451+
LOG_WRN("ADC reading is uncompensated");
398452
}
399453

400454
/* Store result */
401455
data->buffer = (uint16_t *)seq->buffer;
402-
data->buffer[0] = result;
456+
data->buffer[0] = acq_raw;
403457

404458
#else /* !defined(CONFIG_ADC_ESP32_DMA) */
405459

0 commit comments

Comments
 (0)