1use esp_idf_sys::{
2 esp, soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_DEFAULT,
3 temperature_sensor_clk_src_t, temperature_sensor_config_t, temperature_sensor_disable,
4 temperature_sensor_enable, temperature_sensor_get_celsius, temperature_sensor_handle_t,
5 temperature_sensor_install, temperature_sensor_uninstall, EspError,
6};
7
8#[cfg(esp32p4)]
9use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI;
10#[cfg(any(
11 esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
12))]
13use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST;
14#[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
15use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL;
16
17use core::marker::PhantomData;
18
19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22pub enum TempSensorClockSource {
24 Default,
25 #[cfg(any(
26 esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
27 ))]
28 RcFast,
29 #[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
30 XTAL,
31 #[cfg(esp32p4)]
32 LpPeri,
33}
34
35impl From<TempSensorClockSource> for temperature_sensor_clk_src_t {
36 fn from(value: TempSensorClockSource) -> Self {
37 match value {
38 #[cfg(any(
39 esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
40 ))]
41 TempSensorClockSource::RcFast => {
42 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST
43 }
44 #[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
45 TempSensorClockSource::XTAL => {
46 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL
47 }
48 #[cfg(esp32p4)]
49 TempSensorClockSource::LpPeri => {
50 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI
51 }
52 TempSensorClockSource::Default => {
53 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_DEFAULT
54 }
55 }
56 }
57}
58
59impl From<temperature_sensor_clk_src_t> for TempSensorClockSource {
60 fn from(value: temperature_sensor_clk_src_t) -> Self {
61 match value {
62 #[cfg(any(
63 esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32s2, esp32s3
64 ))]
65 #[allow(non_upper_case_globals)]
66 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_RC_FAST => {
67 Self::RcFast
68 }
69 #[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))]
70 #[allow(non_upper_case_globals)]
71 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL => Self::XTAL,
72 #[cfg(esp32p4)]
73 #[allow(non_upper_case_globals)]
74 soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_LP_PERI => {
75 Self::LpPeri
76 }
77 _ => Self::Default,
80 }
81 }
82}
83
84pub type TempSensorConfig = config::Config;
86pub mod config {
87 use super::*;
88 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
89 #[non_exhaustive]
90 pub struct Config {
92 pub range_min: i32,
94 pub range_max: i32,
95 pub clk_src: TempSensorClockSource,
96 }
97
98 impl From<temperature_sensor_config_t> for Config {
99 fn from(value: temperature_sensor_config_t) -> Self {
100 Config {
101 range_min: value.range_min,
102 range_max: value.range_max,
103 clk_src: value.clk_src.into(),
104 }
105 }
106 }
107
108 #[allow(clippy::needless_update)]
109 impl From<&Config> for temperature_sensor_config_t {
110 fn from(value: &Config) -> Self {
111 temperature_sensor_config_t {
112 clk_src: value.clk_src.into(),
113 range_max: value.range_max,
114 range_min: value.range_min,
115 ..Default::default()
116 }
117 }
118 }
119
120 impl Default for Config {
121 fn default() -> Self {
122 Config::new()
123 }
124 }
125
126 impl Config {
127 pub const fn new() -> Self {
128 Self {
129 range_min: -10,
130 range_max: 80,
131 clk_src: TempSensorClockSource::Default,
132 }
133 }
134 }
135}
136
137pub struct TempSensorDriver<'d> {
140 ptr: temperature_sensor_handle_t,
141 _p: PhantomData<&'d mut ()>,
142}
143
144impl<'d> TempSensorDriver<'d> {
145 pub fn new(config: &TempSensorConfig, _sensor: TempSensor<'d>) -> Result<Self, EspError> {
146 let mut sensor = core::ptr::null_mut();
147 esp!(unsafe { temperature_sensor_install(&config.into(), &mut sensor) })?;
148 Ok(TempSensorDriver {
149 ptr: sensor,
150 _p: PhantomData,
151 })
152 }
153
154 pub fn enable(&mut self) -> Result<(), EspError> {
155 esp!(unsafe { temperature_sensor_enable(self.ptr) })
156 }
157
158 pub fn disable(&mut self) -> Result<(), EspError> {
159 esp!(unsafe { temperature_sensor_disable(self.ptr) })
160 }
161
162 pub fn get_celsius(&self) -> Result<f32, EspError> {
163 let mut val = 0.0;
164 esp!(unsafe { temperature_sensor_get_celsius(self.ptr, &mut val) })?;
165 Ok(val)
166 }
167
168 pub fn get_fahrenheit(&self) -> Result<f32, EspError> {
169 let celsius = self.get_celsius()?;
170 Ok((celsius * 1.8) + 32.0)
171 }
172
173 pub fn get_kelvin(&self) -> Result<f32, EspError> {
174 let celsius = self.get_celsius()?;
175 Ok(celsius + 273.15)
176 }
177}
178
179impl Drop for TempSensorDriver<'_> {
180 fn drop(&mut self) {
181 let _ = self.disable();
182 esp!(unsafe { temperature_sensor_uninstall(self.ptr) }).unwrap();
183 }
184}
185
186unsafe impl Send for TempSensorDriver<'_> {}
187
188crate::impl_peripheral!(TempSensor);