From a8cac78fce1b307a30ebf4fa98a67c66dc39c68a Mon Sep 17 00:00:00 2001 From: Nathan Fox Date: Sun, 24 Apr 2022 21:15:47 -0400 Subject: [PATCH 1/2] add temp/vref controls --- src/adc.rs | 57 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/adc.rs b/src/adc.rs index 873b5b58..cb76abd8 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -15,6 +15,9 @@ use embedded_dma::WriteBuffer; use crate::pac::{self, RCC}; +const TEMP_CHANNEL: u8 = 16; +const VREF_CHANNEL: u8 = 17; + /// Continuous mode pub struct Continuous; /// Scan mode @@ -456,7 +459,29 @@ macro_rules! adc_hal { impl Adc { fn read_aux(&mut self, chan: u8) -> u16 { - let tsv_off = if self.rb.cr2.read().tsvrefe().bit_is_clear() { + let tsv_enabled = if chan == TEMP_CHANNEL || chan == VREF_CHANNEL { + self.enable_temp_vref() + } else { + false + }; + + let val = self.convert(chan); + + if tsv_enabled { + self.disable_temp_vref(); + } + + val + } + + /// Enables the temperature / VREF sensor. + /// + /// Enabling this before calling `read_temp` or `read_vref` will speed up the reading + /// since you won't have to wait for the sensor to start up. + /// + /// Returns true if the sensor was previously off. + pub fn enable_temp_vref(&mut self) -> bool { + if !self.is_temp_vref_enabled() { self.rb.cr2.modify(|_, w| w.tsvrefe().set_bit()); // The reference manual says that a stabilization time is needed after the powering the @@ -467,15 +492,19 @@ impl Adc { true } else { false - }; - - let val = self.convert(chan); - - if tsv_off { - self.rb.cr2.modify(|_, w| w.tsvrefe().clear_bit()); } + } - val + /// Disables the temperature / VREF sensor. + /// + /// `read_temp` and `read_vref` will still work with this disabled, but will take a + /// bit longer since you have to wait for the sensor to start up. + pub fn disable_temp_vref(&mut self) { + self.rb.cr2.modify(|_, w| w.tsvrefe().clear_bit()); + } + + pub fn is_temp_vref_enabled(&self) -> bool { + self.rb.cr2.read().tsvrefe().bit_is_set() } /// Temperature sensor is connected to channel 16 on ADC1. This sensor can be used @@ -490,6 +519,9 @@ impl Adc { /// temperature readings are needed, an external temperature sensor part should be used." /// /// Formula to calculate temperature value is also taken from the section 11.10. + /// + /// If the temp/VREF sensor is disabled, this will still work but must wait + /// for the sensor to start up. Call `enable_temp_vref` to speed this up. pub fn read_temp(&mut self) -> i32 { /// According to section 5.3.18 "Temperature sensor characteristics" /// from STM32F1xx datasheets, TS constants values are as follows: @@ -515,8 +547,8 @@ impl Adc { }; self.set_sample_time(sample_time); - let val_temp: i32 = self.read_aux(16u8).into(); - let val_vref: i32 = self.read_aux(17u8).into(); + let val_temp: i32 = self.read_aux(TEMP_CHANNEL).into(); + let val_vref: i32 = self.read_aux(VREF_CHANNEL).into(); let v_sense = val_temp * 1200 / val_vref; self.restore_cfg(prev_cfg); @@ -532,8 +564,11 @@ impl Adc { /// For instance, reading from any ADC channel can be converted into voltage (mV) /// using the following formula: /// v_chan = adc.read(chan) * 1200 / adc.read_vref() + /// + /// If the temp/VREF sensor is disabled, this will still work but must wait + /// for the sensor to start up. Call `enable_temp_vref` to speed this up. pub fn read_vref(&mut self) -> u16 { - self.read_aux(17u8) + self.read_aux(VREF_CHANNEL) } } From 6a8758a9ad4e08c3cfe0c5623896dac00ad91d5e Mon Sep 17 00:00:00 2001 From: Nathan Fox Date: Mon, 13 Jun 2022 21:20:19 -0400 Subject: [PATCH 2/2] add to CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9744ad3d..9bdb5159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Allow access to the `Tx` and `Rx` parts of the `Serial` without the need for splitting. - Allow `Serial` reconfiguration by references to the `Tx` and `Rx` parts. - Allow `Serial` release after splitting. +- Added ADC methods for temp/vref sensor control. The time required for reading from the ADC can be reduced using these. ## [v0.9.0] - 2022-03-02