#![cfg_attr(docsrs, procmacros::doc_replace)]
use crate::{
peripherals::{APB_SARADC, TSENS},
system::GenericPeripheralGuard,
};
#[derive(Debug, Clone, Default, PartialEq, Eq, Copy, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum ClockSource {
RcFast,
#[default]
Xtal,
}
#[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,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
#[non_exhaustive]
pub enum ConfigError {}
#[derive(Debug)]
pub struct Temperature {
pub raw_value: u8,
pub offset: i8,
}
impl Temperature {
#[inline]
pub fn new(raw_value: u8, offset: i8) -> Self {
Self { raw_value, offset }
}
#[inline]
pub fn to_celsius(&self) -> f32 {
(self.raw_value as f32) * 0.4386 - (self.offset as f32) * 27.88 - 20.52
}
#[inline]
pub fn to_fahrenheit(&self) -> f32 {
let celsius = self.to_celsius();
(celsius * 1.8) + 32.0
}
#[inline]
pub fn to_kelvin(&self) -> f32 {
let celsius = self.to_celsius();
celsius + 273.15
}
}
#[derive(Debug)]
pub struct TemperatureSensor<'d> {
_peripheral: TSENS<'d>,
_tsens_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Tsens as u8 }>,
_abp_saradc_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ApbSarAdc as u8 }>,
}
impl<'d> TemperatureSensor<'d> {
pub fn new(peripheral: TSENS<'d>, config: Config) -> Result<Self, ConfigError> {
let apb_saradc_guard = GenericPeripheralGuard::new();
let tsens_guard = GenericPeripheralGuard::new();
let mut tsens = Self {
_peripheral: peripheral,
_tsens_guard: tsens_guard,
_abp_saradc_guard: apb_saradc_guard,
};
tsens.apply_config(&config)?;
tsens.power_up();
Ok(tsens)
}
pub fn power_up(&self) {
debug!("Power up");
APB_SARADC::regs()
.tsens_ctrl()
.modify(|_, w| w.pu().set_bit());
}
pub fn power_down(&self) {
APB_SARADC::regs()
.tsens_ctrl()
.modify(|_, w| w.pu().clear_bit());
}
pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
APB_SARADC::regs().tsens_ctrl2().write(|w| {
w.clk_sel()
.bit(matches!(config.clock_source, ClockSource::Xtal))
});
Ok(())
}
#[inline]
pub fn get_temperature(&self) -> Temperature {
let raw_value = APB_SARADC::regs().tsens_ctrl().read().out().bits();
let offset = -1i8;
Temperature::new(raw_value, offset)
}
}