Skip to content

Commit 2fdc829

Browse files
committed
adc: Adjust the adc resolution with the oversampling factor
The old SAM0 adc drivers forces you to put 12 bits when using oversampling. The adc_raw_to_millivolts_dt function is not working properly because if we uses an oversampling of 8, we get 16 bits of resolution. The function uses directly the resolution in the DT, so the voltage will not be correct. To counter this, i forced the user to put the right resolution for his oversampling factor. Fixes: #74607 Signed-off-by: Robin Carrupt <[email protected]>
1 parent 1159c2a commit 2fdc829

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

drivers/adc/adc_sam0.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,27 +343,60 @@ static int start_read(const struct device *dev,
343343
switch (sequence->resolution) {
344344
case 8:
345345
if (sequence->oversampling) {
346-
LOG_ERR("Oversampling requires 12 bit resolution");
346+
LOG_ERR("Oversampling requires minimum 13 bit resolution");
347347
return -EINVAL;
348348
}
349349

350350
ADC_RESSEL(adc) = ADC_RESSEL_8BIT;
351351
break;
352352
case 10:
353353
if (sequence->oversampling) {
354-
LOG_ERR("Oversampling requires 12 bit resolution");
354+
LOG_ERR("Oversampling requires minimum 13 bit resolution");
355355
return -EINVAL;
356356
}
357357

358358
ADC_RESSEL(adc) = ADC_RESSEL_10BIT;
359359
break;
360360
case 12:
361361
if (sequence->oversampling) {
362-
ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
362+
LOG_ERR("Oversampling requires minimum 13 bit resolution");
363+
return -EINVAL;
363364
} else {
364365
ADC_RESSEL(adc) = ADC_RESSEL_12BIT;
365366
}
366367
break;
368+
case 13:
369+
if (sequence->oversampling != 2U) {
370+
LOG_ERR("13 bit resolution requires an oversampling of 2");
371+
return -EINVAL;
372+
} else {
373+
ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
374+
}
375+
break;
376+
case 14:
377+
if (sequence->oversampling != 4U) {
378+
LOG_ERR("14 bit resolution requires an oversampling of 4");
379+
return -EINVAL;
380+
} else {
381+
ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
382+
}
383+
break;
384+
case 15:
385+
if (sequence->oversampling != 6U) {
386+
LOG_ERR("15 bit resolution requires an oversampling of 6");
387+
return -EINVAL;
388+
} else {
389+
ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
390+
}
391+
break;
392+
case 16:
393+
if (sequence->oversampling != 8U) {
394+
LOG_ERR("16 bit resolution requires an oversampling of 8");
395+
return -EINVAL;
396+
} else {
397+
ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
398+
}
399+
break;
367400
default:
368401
LOG_ERR("ADC resolution value %d is not valid",
369402
sequence->resolution);

0 commit comments

Comments
 (0)