@@ -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+
4850struct 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+
96134static 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