Skip to content

Commit

Permalink
Merge #397
Browse files Browse the repository at this point in the history
397: fix #362: ADC voltage conversion might be incorrect r=burrbull a=gernoteger

since the discussion in #362 seems to come to a conclusion, and my personal measurements supported that, I think it's time to actually fix it.
This will change max_sample from 1<<n-1 to 1<<n,
After this PR ADC readings will change, but will be more accurate than before. Users might be confused since they won't get a reading of 3300mV, but this is correct behaviour.

Co-authored-by: gernot <gernot.eger@gmail.com>
  • Loading branch information
bors[bot] and gernoteger authored Dec 11, 2021
2 parents d1123d8 + d9a9cd2 commit 9424a37
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [breaking-change] Make `Alternate` generic over `Otype` instead of separate `Alternate` and `AlternateOD` [#383]
- [breaking-change] Bump `stm32f4` to 0.14. Update RTIC based examples to use `rtic` 0.6 [#367]
- [breaking-change] Bump `bxcan` to 0.6 [#371]
- fix #362: ADC voltage conversion might be incorrect [#397]

[#367]: https://github.com/stm32-rs/stm32f4xx-hal/pull/397
[#367]: https://github.com/stm32-rs/stm32f4xx-hal/pull/367
[#371]: https://github.com/stm32-rs/stm32f4xx-hal/pull/371
[#383]: https://github.com/stm32-rs/stm32f4xx-hal/pull/383
Expand Down
14 changes: 8 additions & 6 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ pub struct Adc<ADC> {
adc_reg: ADC,
/// VDDA in millivolts calculated from the factory calibration and vrefint
calibrated_vdda: u32,
/// Maximum sample value possible for the configured resolution
/// Exclusive limit for the sample value possible for the configured resolution.
max_sample: u32,
}
impl<ADC> fmt::Debug for Adc<ADC> {
Expand Down Expand Up @@ -794,10 +794,10 @@ macro_rules! adc {
/// Sets the sampling resolution
pub fn set_resolution(&mut self, resolution: config::Resolution) {
self.max_sample = match resolution {
config::Resolution::Twelve => (1 << 12) - 1,
config::Resolution::Ten => (1 << 10) - 1,
config::Resolution::Eight => (1 << 8) - 1,
config::Resolution::Six => (1 << 6) -1,
config::Resolution::Twelve => (1 << 12),
config::Resolution::Ten => (1 << 10),
config::Resolution::Eight => (1 << 8),
config::Resolution::Six => (1 << 6),
};
self.config.resolution = resolution;
self.adc_reg.cr1.modify(|_, w| w.res().bits(resolution.into()));
Expand Down Expand Up @@ -954,7 +954,9 @@ macro_rules! adc {
self.adc_reg.dr.read().data().bits()
}

/// Converts a sample value to millivolts using calibrated VDDA and configured resolution
/// Converts a sample value to millivolts using calibrated VDDA and configured resolution.
/// Due to the ADC characteristics VDDA will never be reached as described in #362 and
/// [AN2834-How to get the best ADC accuracy in STM32 microcontrollers](https://www.st.com/resource/en/application_note/cd00211314-how-to-get-the-best-adc-accuracy-in-stm32-microcontrollers-stmicroelectronics.pdf) in section 3.1.2.
pub fn sample_to_millivolts(&self, sample: u16) -> u16 {
((u32::from(sample) * self.calibrated_vdda) / self.max_sample) as u16
}
Expand Down

0 comments on commit 9424a37

Please sign in to comment.