Skip to content

Commit 3c00621

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

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-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: 42 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,25 @@ 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 = matches!(chan, TEMP_CHANNEL | VREF_CHANNEL) && self.enable_temp_vref();
504+
505+
let val = self.convert(chan);
506+
507+
if tsv_enabled {
508+
self.disable_temp_vref();
509+
}
510+
511+
val
512+
}
513+
514+
/// Enables the temperature / VREF sensor.
515+
///
516+
/// Enabling this before calling `read_temp` or `read_vref` will speed up the reading
517+
/// since you won't have to wait for the sensor to start up.
518+
///
519+
/// Returns true if the sensor was previously off.
520+
pub fn enable_temp_vref(&mut self) -> bool {
521+
if !self.is_temp_vref_enabled() {
501522
self.rb.cr2().modify(|_, w| w.tsvrefe().set_bit());
502523

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

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

522547
/// Temperature sensor is connected to channel 16 on ADC1. This sensor can be used
@@ -531,6 +556,9 @@ impl Adc<pac::ADC1> {
531556
/// temperature readings are needed, an external temperature sensor part should be used."
532557
///
533558
/// Formula to calculate temperature value is also taken from the section 11.10.
559+
///
560+
/// If the temp/VREF sensor is disabled, this will still work but must wait
561+
/// for the sensor to start up. Call `enable_temp_vref` to speed this up.
534562
pub fn read_temp(&mut self) -> i32 {
535563
/// According to section 5.3.18 "Temperature sensor characteristics"
536564
/// from STM32F1xx datasheets, TS constants values are as follows:
@@ -556,8 +584,8 @@ impl Adc<pac::ADC1> {
556584
};
557585

558586
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();
587+
let val_temp: i32 = self.read_aux(TEMP_CHANNEL).into();
588+
let val_vref: i32 = self.read_aux(VREF_CHANNEL).into();
561589
let v_sense = val_temp * 1200 / val_vref;
562590

563591
self.restore_cfg(prev_cfg);
@@ -573,8 +601,11 @@ impl Adc<pac::ADC1> {
573601
/// For instance, reading from any ADC channel can be converted into voltage (mV)
574602
/// using the following formula:
575603
/// v_chan = adc.read(chan) * 1200 / adc.read_vref()
604+
///
605+
/// If the temp/VREF sensor is disabled, this will still work but must wait
606+
/// for the sensor to start up. Call `enable_temp_vref` to speed this up.
576607
pub fn read_vref(&mut self) -> u16 {
577-
self.read_aux(17u8)
608+
self.read_aux(VREF_CHANNEL)
578609
}
579610
}
580611

0 commit comments

Comments
 (0)