stm32/adc: Remove voltage and temperature conversions
This commit is contained in:
		| @@ -86,7 +86,6 @@ pub use sample_time::SampleTime; | ||||
|  | ||||
| pub struct Adc<'d, T: Instance> { | ||||
|     sample_time: SampleTime, | ||||
|     calibrated_vdda: u32, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| } | ||||
|  | ||||
| @@ -122,7 +121,6 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|  | ||||
|         Self { | ||||
|             sample_time: Default::default(), | ||||
|             calibrated_vdda: VDDA_CALIB_MV, | ||||
|             phantom: PhantomData, | ||||
|         } | ||||
|     } | ||||
| @@ -162,29 +160,10 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|         Temperature {} | ||||
|     } | ||||
|  | ||||
|     /// Calculates the system VDDA by sampling the internal VREF channel and comparing | ||||
|     /// to the expected value. If the chip's VDDA is not stable, run this before each ADC | ||||
|     /// conversion. | ||||
|     pub fn calibrate(&mut self, vref: &mut Vref) -> u32 { | ||||
|         let old_sample_time = self.sample_time; | ||||
|         self.sample_time = SampleTime::Cycles239_5; | ||||
|  | ||||
|         let vref_samp = self.read(vref); | ||||
|         self.sample_time = old_sample_time; | ||||
|  | ||||
|         self.calibrated_vdda = (ADC_MAX * VREF_INT) / u32::from(vref_samp); | ||||
|         self.calibrated_vdda | ||||
|     } | ||||
|  | ||||
|     pub fn set_sample_time(&mut self, sample_time: SampleTime) { | ||||
|         self.sample_time = sample_time; | ||||
|     } | ||||
|  | ||||
|     /// Convert a measurement to millivolts | ||||
|     pub fn to_millivolts(&self, sample: u16) -> u16 { | ||||
|         ((u32::from(sample) * self.calibrated_vdda) / ADC_MAX) as u16 | ||||
|     } | ||||
|  | ||||
|     /// Perform a single conversion. | ||||
|     fn convert(&mut self) -> u16 { | ||||
|         unsafe { | ||||
|   | ||||
| @@ -80,15 +80,6 @@ impl super::sealed::InternalChannel<ADC1> for Temperature { | ||||
| } | ||||
|  | ||||
| impl Temperature { | ||||
|     /// Converts temperature sensor reading in millivolts to degrees celcius | ||||
|     pub fn to_celcius(sample_mv: u16) -> f32 { | ||||
|         // From 6.3.22 Temperature sensor characteristics | ||||
|         const V25: i32 = 760; // mV | ||||
|         const AVG_SLOPE: f32 = 2.5; // mV/C | ||||
|  | ||||
|         (sample_mv as i32 - V25) as f32 / AVG_SLOPE + 25.0 | ||||
|     } | ||||
|  | ||||
|     /// Time needed for temperature sensor readings to stabilize | ||||
|     pub fn start_time_us() -> u32 { | ||||
|         10 | ||||
| @@ -172,7 +163,6 @@ impl Prescaler { | ||||
|  | ||||
| pub struct Adc<'d, T: Instance> { | ||||
|     sample_time: SampleTime, | ||||
|     vref_mv: u32, | ||||
|     resolution: Resolution, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| } | ||||
| @@ -200,7 +190,6 @@ where | ||||
|         Self { | ||||
|             sample_time: Default::default(), | ||||
|             resolution: Resolution::default(), | ||||
|             vref_mv: VREF_DEFAULT_MV, | ||||
|             phantom: PhantomData, | ||||
|         } | ||||
|     } | ||||
| @@ -213,18 +202,6 @@ where | ||||
|         self.resolution = resolution; | ||||
|     } | ||||
|  | ||||
|     /// Set VREF value in millivolts. This value is used for [to_millivolts()] sample conversion. | ||||
|     /// | ||||
|     /// Use this if you have a known precise VREF (VDDA) pin reference voltage. | ||||
|     pub fn set_vref_mv(&mut self, vref_mv: u32) { | ||||
|         self.vref_mv = vref_mv; | ||||
|     } | ||||
|  | ||||
|     /// Convert a measurement to millivolts | ||||
|     pub fn to_millivolts(&self, sample: u16) -> u16 { | ||||
|         ((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16 | ||||
|     } | ||||
|  | ||||
|     /// Enables internal voltage reference and returns [VrefInt], which can be used in | ||||
|     /// [Adc::read_internal()] to perform conversion. | ||||
|     pub fn enable_vrefint(&self) -> VrefInt { | ||||
|   | ||||
| @@ -205,7 +205,6 @@ pub use sample_time::SampleTime; | ||||
|  | ||||
| pub struct Adc<'d, T: Instance> { | ||||
|     sample_time: SampleTime, | ||||
|     vref_mv: u32, | ||||
|     resolution: Resolution, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| } | ||||
| @@ -244,7 +243,6 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|         Self { | ||||
|             sample_time: Default::default(), | ||||
|             resolution: Resolution::default(), | ||||
|             vref_mv: VREF_DEFAULT_MV, | ||||
|             phantom: PhantomData, | ||||
|         } | ||||
|     } | ||||
| @@ -285,31 +283,6 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|         Vbat {} | ||||
|     } | ||||
|  | ||||
|     /// Calculates the system VDDA by sampling the internal VREFINT channel and comparing | ||||
|     /// the result with the value stored at the factory. If the chip's VDDA is not stable, run | ||||
|     /// this before each ADC conversion. | ||||
|     #[cfg(not(stm32g0))] // TODO is this supposed to be public? | ||||
|     #[allow(unused)] // TODO is this supposed to be public? | ||||
|     fn calibrate(&mut self, vrefint: &mut VrefInt) { | ||||
|         #[cfg(stm32l5)] | ||||
|         let vrefint_cal: u32 = todo!(); | ||||
|         #[cfg(not(stm32l5))] | ||||
|         let vrefint_cal = unsafe { crate::pac::VREFINTCAL.data().read().value() }; | ||||
|         let old_sample_time = self.sample_time; | ||||
|  | ||||
|         // "Table 24. Embedded internal voltage reference" states that the sample time needs to be | ||||
|         // at a minimum 4 us. With 640.5 ADC cycles we have a minimum of 8 us at 80 MHz, leaving | ||||
|         // some headroom. | ||||
|         self.sample_time = SampleTime::Cycles640_5; | ||||
|  | ||||
|         // This can't actually fail, it's just in a result to satisfy hal trait | ||||
|         let vrefint_samp = self.read(vrefint); | ||||
|  | ||||
|         self.sample_time = old_sample_time; | ||||
|  | ||||
|         self.vref_mv = (VREF_CALIB_MV * u32::from(vrefint_cal)) / u32::from(vrefint_samp); | ||||
|     } | ||||
|  | ||||
|     pub fn set_sample_time(&mut self, sample_time: SampleTime) { | ||||
|         self.sample_time = sample_time; | ||||
|     } | ||||
| @@ -318,18 +291,6 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|         self.resolution = resolution; | ||||
|     } | ||||
|  | ||||
|     /// Set VREF value in millivolts. This value is used for [to_millivolts()] sample conversion. | ||||
|     /// | ||||
|     /// Use this if you have a known precise VREF (VDDA) pin reference voltage. | ||||
|     pub fn set_vref_mv(&mut self, vref_mv: u32) { | ||||
|         self.vref_mv = vref_mv; | ||||
|     } | ||||
|  | ||||
|     /// Convert a measurement to millivolts | ||||
|     pub fn to_millivolts(&self, sample: u16) -> u16 { | ||||
|         ((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16 | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     /// Convert a raw sample from the `Temperature` to deg C | ||||
|     pub fn to_degrees_centigrade(sample: u16) -> f32 { | ||||
|   | ||||
| @@ -314,7 +314,6 @@ impl Prescaler { | ||||
|  | ||||
| pub struct Adc<'d, T: Instance> { | ||||
|     sample_time: SampleTime, | ||||
|     vref_mv: u32, | ||||
|     resolution: Resolution, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| } | ||||
| @@ -352,7 +351,6 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | ||||
|  | ||||
|         let mut s = Self { | ||||
|             sample_time: Default::default(), | ||||
|             vref_mv: VREF_DEFAULT_MV, | ||||
|             resolution: Resolution::default(), | ||||
|             phantom: PhantomData, | ||||
|         }; | ||||
| @@ -459,18 +457,6 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | ||||
|         self.resolution = resolution; | ||||
|     } | ||||
|  | ||||
|     /// Set VREF value in millivolts. This value is used for [to_millivolts()] sample conversion. | ||||
|     /// | ||||
|     /// Use this if you have a known precise VREF (VDDA) pin reference voltage. | ||||
|     pub fn set_vref_mv(&mut self, vref_mv: u32) { | ||||
|         self.vref_mv = vref_mv; | ||||
|     } | ||||
|  | ||||
|     /// Convert a measurement to millivolts | ||||
|     pub fn to_millivolts(&self, sample: u16) -> u16 { | ||||
|         ((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16 | ||||
|     } | ||||
|  | ||||
|     /// Perform a single conversion. | ||||
|     fn convert(&mut self) -> u16 { | ||||
|         unsafe { | ||||
|   | ||||
| @@ -17,10 +17,18 @@ async fn main(_spawner: Spawner) { | ||||
|     let mut pin = p.PB1; | ||||
|  | ||||
|     let mut vref = adc.enable_vref(&mut Delay); | ||||
|     adc.calibrate(&mut vref); | ||||
|     let vref_sample = adc.read(&mut vref); | ||||
|     let convert_to_millivolts = |sample| { | ||||
|         // From http://www.st.com/resource/en/datasheet/CD00161566.pdf | ||||
|         // 5.3.4 Embedded reference voltage | ||||
|         const VREF_MV: u32 = 1200; | ||||
|  | ||||
|         (u32::from(sample) * VREF_MV / u32::from(vref_sample)) as u16 | ||||
|     }; | ||||
|  | ||||
|     loop { | ||||
|         let v = adc.read(&mut pin); | ||||
|         info!("--> {} - {} mV", v, adc.to_millivolts(v)); | ||||
|         info!("--> {} - {} mV", v, convert_to_millivolts(v)); | ||||
|         Timer::after(Duration::from_millis(100)).await; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -24,19 +24,40 @@ async fn main(_spawner: Spawner) { | ||||
|     // Startup delay can be combined to the maximum of either | ||||
|     delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us())); | ||||
|  | ||||
|     let vref_sample = adc.read_internal(&mut vrefint); | ||||
|  | ||||
|     let convert_to_millivolts = |sample| { | ||||
|         // From http://www.st.com/resource/en/datasheet/DM00071990.pdf | ||||
|         // 6.3.24 Reference voltage | ||||
|         const VREF_MILLIVOLTS: u32 = 1210; // mV | ||||
|  | ||||
|         (u32::from(sample) * VREF_MILLIVOLTS / u32::from(vref_sample)) as u16 | ||||
|     }; | ||||
|  | ||||
|     let convert_to_celcius = |sample| { | ||||
|         // From http://www.st.com/resource/en/datasheet/DM00071990.pdf | ||||
|         // 6.3.22 Temperature sensor characteristics | ||||
|         const V25: i32 = 760; // mV | ||||
|         const AVG_SLOPE: f32 = 2.5; // mV/C | ||||
|  | ||||
|         let sample_mv = convert_to_millivolts(sample) as i32; | ||||
|  | ||||
|         (sample_mv - V25) as f32 / AVG_SLOPE + 25.0 | ||||
|     }; | ||||
|  | ||||
|     loop { | ||||
|         // Read pin | ||||
|         let v = adc.read(&mut pin); | ||||
|         info!("PC1: {} ({} mV)", v, adc.to_millivolts(v)); | ||||
|         info!("PC1: {} ({} mV)", v, convert_to_millivolts(v)); | ||||
|  | ||||
|         // Read internal temperature | ||||
|         let v = adc.read_internal(&mut temp); | ||||
|         let celcius = Temperature::to_celcius(adc.to_millivolts(v)); | ||||
|         let celcius = convert_to_celcius(v); | ||||
|         info!("Internal temp: {} ({} C)", v, celcius); | ||||
|  | ||||
|         // Read internal voltage reference | ||||
|         let v = adc.read_internal(&mut vrefint); | ||||
|         info!("VrefInt: {} ({} mV)", v, adc.to_millivolts(v)); | ||||
|         info!("VrefInt: {} ({} mV)", v, convert_to_millivolts(v)); | ||||
|  | ||||
|         Timer::after(Duration::from_millis(100)).await; | ||||
|     } | ||||
|   | ||||
| @@ -16,9 +16,19 @@ async fn main(_spawner: Spawner) { | ||||
|     let mut adc = Adc::new(p.ADC1, &mut Delay); | ||||
|     let mut pin = p.PA3; | ||||
|  | ||||
|     let mut vref = adc.enable_vrefint(); | ||||
|     let vref_sample = adc.read_internal(&mut vref); | ||||
|     let convert_to_millivolts = |sample| { | ||||
|         // From http://www.st.com/resource/en/datasheet/DM00273119.pdf | ||||
|         // 6.3.27 Reference voltage | ||||
|         const VREF_MV: u32 = 1210; | ||||
|  | ||||
|         (u32::from(sample) * VREF_MV / u32::from(vref_sample)) as u16 | ||||
|     }; | ||||
|  | ||||
|     loop { | ||||
|         let v = adc.read(&mut pin); | ||||
|         info!("--> {} - {} mV", v, adc.to_millivolts(v)); | ||||
|         info!("--> {} - {} mV", v, convert_to_millivolts(v)); | ||||
|         Timer::after(Duration::from_millis(100)).await; | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user