Skip to content

Commit 1fa025f

Browse files
fuchsnjburrbull
authored andcommitted
add temp/vref controls
1 parent 5dd7b0f commit 1fa025f

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
4646
- `Serial` support for UART4/5
4747
- Allow to set HSE bypass bit in `RCC` clock configuration register to use an external clock input on the `OSC_IN` pin [#485]
4848
- initial support of `embedded-hal-1.0` [#416]
49+
- Added ADC methods for temp/vref sensor control. The time required for reading from the ADC can be reduced using these [#422]
4950
- Add tools/check.py python script for local check [#467]
5051
- Add changelog check on PRs [#467]
5152
- Reexport `Direction` from `qei` [#479]
@@ -56,6 +57,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5657
- Add enable/disable EOC interrupt functions for ADCs [#526]
5758

5859
[#416]: https://github.com/stm32-rs/stm32f1xx-hal/pull/416
60+
[#422]: https://github.com/stm32-rs/stm32f1xx-hal/pull/422
5961
[#453]: https://github.com/stm32-rs/stm32f1xx-hal/pull/453
6062
[#462]: https://github.com/stm32-rs/stm32f1xx-hal/pull/462
6163
[#467]: https://github.com/stm32-rs/stm32f1xx-hal/pull/467

src/adc.rs

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ use embedded_dma::WriteBuffer;
1818
use crate::pac::{self, RCC};
1919
use crate::pacext::adc::{AdcRB, Cr1W, Cr2R, Cr2W, Dr, ExtSelW};
2020

21+
const TEMP_CHANNEL: u8 = 16;
22+
const VREF_CHANNEL: u8 = 17;
23+
2124
/// Continuous mode
2225
pub struct Continuous;
2326
/// Scan mode
@@ -497,7 +500,29 @@ where
497500

498501
impl Adc<pac::ADC1> {
499502
fn read_aux(&mut self, chan: u8) -> u16 {
500-
let tsv_off = if self.rb.cr2().read().tsvrefe().bit_is_clear() {
503+
let tsv_enabled = if matches!(chan, TEMP_CHANNEL | VREF_CHANNEL) {
504+
self.enable_temp_vref()
505+
} else {
506+
false
507+
};
508+
509+
let val = self.convert(chan);
510+
511+
if tsv_enabled {
512+
self.disable_temp_vref();
513+
}
514+
515+
val
516+
}
517+
518+
/// Enables the temperature / VREF sensor.
519+
///
520+
/// Enabling this before calling `read_temp` or `read_vref` will speed up the reading
521+
/// since you won't have to wait for the sensor to start up.
522+
///
523+
/// Returns true if the sensor was previously off.
524+
pub fn enable_temp_vref(&mut self) -> bool {
525+
if !self.is_temp_vref_enabled() {
501526
self.rb.cr2().modify(|_, w| w.tsvrefe().set_bit());
502527

503528
// The reference manual says that a stabilization time is needed after the powering the
@@ -508,15 +533,19 @@ impl Adc<pac::ADC1> {
508533
true
509534
} else {
510535
false
511-
};
512-
513-
let val = self.convert(chan);
514-
515-
if tsv_off {
516-
self.rb.cr2().modify(|_, w| w.tsvrefe().clear_bit());
517536
}
537+
}
518538

519-
val
539+
/// Disables the temperature / VREF sensor.
540+
///
541+
/// `read_temp` and `read_vref` will still work with this disabled, but will take a
542+
/// bit longer since you have to wait for the sensor to start up.
543+
pub fn disable_temp_vref(&mut self) {
544+
self.rb.cr2().modify(|_, w| w.tsvrefe().clear_bit());
545+
}
546+
547+
pub fn is_temp_vref_enabled(&self) -> bool {
548+
self.rb.cr2().read().tsvrefe().bit_is_set()
520549
}
521550

522551
/// Temperature sensor is connected to channel 16 on ADC1. This sensor can be used
@@ -531,6 +560,9 @@ impl Adc<pac::ADC1> {
531560
/// temperature readings are needed, an external temperature sensor part should be used."
532561
///
533562
/// Formula to calculate temperature value is also taken from the section 11.10.
563+
///
564+
/// If the temp/VREF sensor is disabled, this will still work but must wait
565+
/// for the sensor to start up. Call `enable_temp_vref` to speed this up.
534566
pub fn read_temp(&mut self) -> i32 {
535567
/// According to section 5.3.18 "Temperature sensor characteristics"
536568
/// from STM32F1xx datasheets, TS constants values are as follows:
@@ -556,8 +588,8 @@ impl Adc<pac::ADC1> {
556588
};
557589

558590
self.set_sample_time(sample_time);
559-
let val_temp: i32 = self.read_aux(16u8).into();
560-
let val_vref: i32 = self.read_aux(17u8).into();
591+
let val_temp: i32 = self.read_aux(TEMP_CHANNEL).into();
592+
let val_vref: i32 = self.read_aux(VREF_CHANNEL).into();
561593
let v_sense = val_temp * 1200 / val_vref;
562594

563595
self.restore_cfg(prev_cfg);
@@ -573,8 +605,11 @@ impl Adc<pac::ADC1> {
573605
/// For instance, reading from any ADC channel can be converted into voltage (mV)
574606
/// using the following formula:
575607
/// v_chan = adc.read(chan) * 1200 / adc.read_vref()
608+
///
609+
/// If the temp/VREF sensor is disabled, this will still work but must wait
610+
/// for the sensor to start up. Call `enable_temp_vref` to speed this up.
576611
pub fn read_vref(&mut self) -> u16 {
577-
self.read_aux(17u8)
612+
self.read_aux(VREF_CHANNEL)
578613
}
579614
}
580615

0 commit comments

Comments
 (0)