use esp_idf_sys::{
esp, soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_DEFAULT,
temperature_sensor_clk_src_t, temperature_sensor_config_t, temperature_sensor_disable,
temperature_sensor_enable, temperature_sensor_get_celsius, temperature_sensor_handle_t,
temperature_sensor_install, temperature_sensor_uninstall, EspError,
};
#[cfg(esp32p4)]
use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI;
#[cfg(any(
esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
))]
use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST;
#[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL;
use crate::peripheral::Peripheral;
use core::marker::PhantomData;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TempSensorClockSource {
Default,
#[cfg(any(
esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
))]
RcFast,
#[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
XTAL,
#[cfg(esp32p4)]
LpPeri,
}
impl From<TempSensorClockSource> for temperature_sensor_clk_src_t {
fn from(value: TempSensorClockSource) -> Self {
match value {
#[cfg(any(
esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
))]
TempSensorClockSource::RcFast => {
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST
}
#[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
TempSensorClockSource::XTAL => {
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL
}
#[cfg(esp32p4)]
TempSensorClockSource::LpPeri => {
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI
}
TempSensorClockSource::Default => {
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_DEFAULT
}
}
}
}
impl From<temperature_sensor_clk_src_t> for TempSensorClockSource {
fn from(value: temperature_sensor_clk_src_t) -> Self {
match value {
#[cfg(any(
esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
))]
#[allow(non_upper_case_globals)]
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST => {
Self::RcFast
}
#[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
#[allow(non_upper_case_globals)]
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL => Self::XTAL,
#[cfg(esp32p4)]
#[allow(non_upper_case_globals)]
soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI => {
Self::LpPeri
}
_ => Self::Default,
}
}
}
pub type TempSensorConfig = config::Config;
pub mod config {
use super::*;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Config {
pub range_min: i32,
pub range_max: i32,
pub clk_src: TempSensorClockSource,
}
impl From<temperature_sensor_config_t> for Config {
fn from(value: temperature_sensor_config_t) -> Self {
Config {
range_min: value.range_min,
range_max: value.range_max,
clk_src: value.clk_src.into(),
}
}
}
#[allow(clippy::needless_update)]
impl From<&Config> for temperature_sensor_config_t {
fn from(value: &Config) -> Self {
temperature_sensor_config_t {
clk_src: value.clk_src.into(),
range_max: value.range_max,
range_min: value.range_min,
..Default::default()
}
}
}
impl Default for Config {
fn default() -> Self {
Config::new()
}
}
impl Config {
pub const fn new() -> Self {
Self {
range_min: -10,
range_max: 80,
clk_src: TempSensorClockSource::Default,
}
}
}
}
pub struct TempSensorDriver<'d> {
ptr: temperature_sensor_handle_t,
_p: PhantomData<&'d mut ()>,
}
impl<'d> TempSensorDriver<'d> {
pub fn new(
config: &TempSensorConfig,
_sensor: impl Peripheral<P = TempSensor> + 'd,
) -> Result<Self, EspError> {
let mut sensor = core::ptr::null_mut();
esp!(unsafe { temperature_sensor_install(&config.into(), &mut sensor) })?;
Ok(TempSensorDriver {
ptr: sensor,
_p: PhantomData,
})
}
pub fn enable(&mut self) -> Result<(), EspError> {
esp!(unsafe { temperature_sensor_enable(self.ptr) })
}
pub fn disable(&mut self) -> Result<(), EspError> {
esp!(unsafe { temperature_sensor_disable(self.ptr) })
}
pub fn get_celsius(&self) -> Result<f32, EspError> {
let mut val = 0.0;
esp!(unsafe { temperature_sensor_get_celsius(self.ptr, &mut val) })?;
Ok(val)
}
pub fn get_fahrenheit(&self) -> Result<f32, EspError> {
let celsius = self.get_celsius()?;
Ok((celsius * 1.8) + 32.0)
}
pub fn get_kelvin(&self) -> Result<f32, EspError> {
let celsius = self.get_celsius()?;
Ok(celsius + 273.15)
}
}
impl Drop for TempSensorDriver<'_> {
fn drop(&mut self) {
let _ = self.disable();
esp!(unsafe { temperature_sensor_uninstall(self.ptr) }).unwrap();
}
}
unsafe impl Send for TempSensorDriver<'_> {}
crate::impl_peripheral!(TempSensor);