diff --git a/esp-hal/src/tsens.rs b/esp-hal/src/tsens.rs
index e75f9d9fa..6fe5cfc46 100644
--- a/esp-hal/src/tsens.rs
+++ b/esp-hal/src/tsens.rs
@@ -31,10 +31,10 @@
//! Config::default()
//! ).unwrap();
//! let delay = Delay::new();
-//!
+//! delay.delay_micros(200);
//! loop {
-//! let temp = temperature_sensor.get_celsius();
-//! println!("Temperature: {:.2}°C", temp);
+//! let temp = temperature_sensor.get_temperature();
+//! println!("Temperature: {:.2}°C", temp.to_celcius());
//! delay.delay_millis(1_000);
//! }
//! # }
@@ -48,11 +48,11 @@
use crate::{
peripheral::{Peripheral, PeripheralRef},
peripherals::TSENS,
- system::{GenericPeripheralGuard, PeripheralClockControl},
+ system::GenericPeripheralGuard,
};
/// Clock source for the temperature sensor
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Default, PartialEq, Eq, Copy, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ClockSource {
/// Use RC_FAST clock source
@@ -63,48 +63,104 @@ pub enum ClockSource {
}
/// Temperature sensor configuration
-#[derive(Debug, Clone, Default, PartialEq, Eq, Copy, procmacros::BuilderLite)]
+#[derive(Debug, Clone, Default, PartialEq, Eq, Copy, Hash, procmacros::BuilderLite)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+#[non_exhaustive]
pub struct Config {
clock_source: ClockSource,
}
/// Temperature sensor configuration error
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
+#[non_exhaustive]
pub enum ConfigError {}
+/// Temperature value
+/// This struct stores the raw ADC value, and can be used to calculate the
+/// temperature in Celsius using the formula:
+/// `(raw_value * 0.4386) - (offset * 27.88) - 20.52`
+#[derive(Debug)]
+pub struct Temperature {
+ /// Raw ADC value
+ pub raw_value: u8,
+
+ /// Offset value - depends on the temperature range configured
+ pub offset: i8,
+}
+
+impl Temperature {
+ /// Create a new temperature value
+ #[inline]
+ pub fn new(raw_value: u8, offset: i8) -> Self {
+ Self { raw_value, offset }
+ }
+
+ /// Get the temperature in Celsius
+ #[inline]
+ pub fn to_celsius(&self) -> f32 {
+ (self.raw_value as f32) * 0.4386 - (self.offset as f32) * 27.88 - 20.52
+ }
+
+ /// Get the temperature in Fahrenheit
+ #[inline]
+ pub fn to_fahrenheit(&self) -> f32 {
+ let celsius = self.to_celsius();
+ (celsius * 1.8) + 32.0
+ }
+
+ /// Get the temperature in Kelvin
+ #[inline]
+ pub fn to_kelvin(&self) -> f32 {
+ let celsius = self.to_celsius();
+ celsius + 273.15
+ }
+}
+
/// Temperature sensor driver
+#[derive(Debug)]
pub struct TemperatureSensor<'d> {
_peripheral: PeripheralRef<'d, TSENS>,
- _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Tsens as u8 }>,
+ _tsens_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Tsens as u8 }>,
+ _abp_saradc_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ApbSarAdc as u8 }>,
}
impl<'d> TemperatureSensor<'d> {
/// Create a new temperature sensor instance with configuration
+ /// The sensor will be automatically powered up
pub fn new(
peripheral: impl Peripheral
+ 'd,
config: Config,
) -> Result {
crate::into_ref!(peripheral);
- let guard = GenericPeripheralGuard::new();
-
- // We need to enable ApbSarAdc clock before trying to write on the tsens_ctrl
- // register
- PeripheralClockControl::enable(crate::system::Peripheral::ApbSarAdc);
- let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::PTR };
-
- // Power Up
- apb_saradc.tsens_ctrl().write(|w| w.pu().set_bit());
+ // NOTE: We need enable ApbSarAdc before enabling Tsens
+ let apb_saradc_guard = GenericPeripheralGuard::new();
+ let tsens_guard = GenericPeripheralGuard::new();
let mut tsens = Self {
- _guard: guard,
_peripheral: peripheral,
+ _tsens_guard: tsens_guard,
+ _abp_saradc_guard: apb_saradc_guard,
};
tsens.apply_config(&config)?;
+ tsens.power_up();
+
Ok(tsens)
}
+ /// Power up the temperature sensor
+ pub fn power_up(&self) {
+ debug!("Power up");
+ let abp_saradc = unsafe { &*crate::peripherals::APB_SARADC::PTR };
+ abp_saradc.tsens_ctrl().modify(|_, w| w.pu().set_bit());
+ }
+
+ /// Power down the temperature sensor - useful if you want to save power
+ pub fn power_down(&self) {
+ let abp_saradc = unsafe { &*crate::peripherals::APB_SARADC::PTR };
+ abp_saradc.tsens_ctrl().modify(|_, w| w.pu().clear_bit());
+ }
+
/// Change the temperature sensor configuration
pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::PTR };
@@ -118,29 +174,16 @@ impl<'d> TemperatureSensor<'d> {
Ok(())
}
- /// Get the temperature in Celsius
+ /// Get the raw temperature value
#[inline]
- pub fn get_celsius(&self) -> f32 {
+ pub fn get_temperature(&self) -> Temperature {
let abp_saradc = unsafe { &*crate::peripherals::APB_SARADC::PTR };
- let measurement = abp_saradc.tsens_ctrl().read().out().bits();
+ let raw_value = abp_saradc.tsens_ctrl().read().out().bits();
// TODO Address multiple temperature ranges and offsets
- let offset = -1f32;
- (measurement as f32) * 0.4386 - offset * 27.88 - 20.52
- }
+ let offset = -1i8;
- /// Get the temperature in Fahrenheit
- #[inline]
- pub fn get_fahrenheit(&self) -> f32 {
- let celsius = self.get_celsius();
- (celsius * 1.8) + 32.0
- }
-
- /// Get the temperature in Kelvin
- #[inline]
- pub fn get_kelvin(&self) -> f32 {
- let celsius = self.get_celsius();
- celsius + 273.15
+ Temperature::new(raw_value, offset)
}
}
diff --git a/examples/src/bin/temperature_sensor.rs b/qa-test/src/bin/temperature_sensor.rs
similarity index 81%
rename from examples/src/bin/temperature_sensor.rs
rename to qa-test/src/bin/temperature_sensor.rs
index d016bd15c..8158af8d0 100644
--- a/examples/src/bin/temperature_sensor.rs
+++ b/qa-test/src/bin/temperature_sensor.rs
@@ -1,5 +1,5 @@
-//! This example uses the internal temperature sensor to measure the chip's temperature
-//!
+//! This example uses the internal temperature sensor to measure the chip's
+//! temperature
//% CHIPS: esp32c6 esp32c3
@@ -26,8 +26,8 @@ fn main() -> ! {
delay.delay_micros(200);
loop {
- let temp = temperature_sensor.get_celsius();
- println!("Temperature: {:.2}°C", temp);
+ let temp = temperature_sensor.get_temperature();
+ println!("Temperature: {:.2}°C", temp.to_celsius());
delay.delay_millis(1_000);
}
}