embedded_devices/devices/texas_instruments/tmp102/
mod.rs1use embedded_devices_derive::{forward_register_fns, sensor};
71use embedded_interfaces::TransportError;
72use uom::si::f64::ThermodynamicTemperature;
73use uom::si::thermodynamic_temperature::degree_celsius;
74
75pub mod address;
76pub mod registers;
77
78use self::registers::{Configuration, Temperature};
79
80#[derive(Debug, embedded_devices_derive::Measurement)]
82pub struct Measurement {
83 #[measurement(Temperature)]
85 pub temperature: ThermodynamicTemperature,
86}
87
88#[maybe_async_cfg::maybe(
94 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), RegisterInterface),
95 sync(feature = "sync"),
96 async(feature = "async")
97)]
98pub struct TMP102<D: hal::delay::DelayNs, I: embedded_interfaces::registers::RegisterInterface> {
99 delay: D,
101 interface: I,
103}
104
105pub trait TMP102Register {}
106
107#[maybe_async_cfg::maybe(
108 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), I2cDevice),
109 sync(feature = "sync"),
110 async(feature = "async")
111)]
112impl<D, I> TMP102<D, embedded_interfaces::i2c::I2cDevice<I, hal::i2c::SevenBitAddress>>
113where
114 I: hal::i2c::I2c<hal::i2c::SevenBitAddress> + hal::i2c::ErrorType,
115 D: hal::delay::DelayNs,
116{
117 #[inline]
120 pub fn new_i2c(delay: D, interface: I, address: self::address::Address) -> Self {
121 Self {
122 delay,
123 interface: embedded_interfaces::i2c::I2cDevice::new(interface, address.into()),
124 }
125 }
126}
127
128#[forward_register_fns]
129#[sensor(Temperature)]
130#[maybe_async_cfg::maybe(
131 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), RegisterInterface),
132 sync(feature = "sync"),
133 async(feature = "async")
134)]
135impl<D: hal::delay::DelayNs, I: embedded_interfaces::registers::RegisterInterface> TMP102<D, I> {
136 pub async fn read_temperature(&mut self) -> Result<ThermodynamicTemperature, TransportError<(), I::BusError>> {
138 let reg_conf = self.read_register::<Configuration>().await?;
139
140 let raw_temp = self.read_register::<Temperature>().await?.read_raw_temperature() as i32;
142 if reg_conf.read_extended() {
143 Ok(ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 128.0))
144 } else {
145 Ok(ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 256.0))
146 }
147 }
148}
149
150#[maybe_async_cfg::maybe(
151 idents(
152 hal(sync = "embedded_hal", async = "embedded_hal_async"),
153 RegisterInterface,
154 OneshotSensor
155 ),
156 sync(feature = "sync"),
157 async(feature = "async")
158)]
159impl<D: hal::delay::DelayNs, I: embedded_interfaces::registers::RegisterInterface> crate::sensor::OneshotSensor
160 for TMP102<D, I>
161{
162 type Error = TransportError<(), I::BusError>;
163 type Measurement = Measurement;
164
165 async fn measure(&mut self) -> Result<Self::Measurement, Self::Error> {
171 let reg_conf = self.read_register::<Configuration>().await?;
172 self.write_register(reg_conf.with_oneshot(true).with_shutdown(false))
173 .await?;
174
175 self.delay.delay_us(12_500).await;
177
178 let raw_temp = self.read_register::<Temperature>().await?.read_raw_temperature() as i32;
179 if reg_conf.read_extended() {
180 Ok(Measurement {
181 temperature: ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 128.0),
182 })
183 } else {
184 Ok(Measurement {
185 temperature: ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 256.0),
186 })
187 }
188 }
189}
190
191#[maybe_async_cfg::maybe(
192 idents(
193 hal(sync = "embedded_hal", async = "embedded_hal_async"),
194 RegisterInterface,
195 ContinuousSensor
196 ),
197 sync(feature = "sync"),
198 async(feature = "async")
199)]
200impl<D: hal::delay::DelayNs, I: embedded_interfaces::registers::RegisterInterface> crate::sensor::ContinuousSensor
201 for TMP102<D, I>
202{
203 type Error = TransportError<(), I::BusError>;
204 type Measurement = Measurement;
205
206 async fn start_measuring(&mut self) -> Result<(), Self::Error> {
208 let reg_conf = self.read_register::<Configuration>().await?;
209 self.write_register(reg_conf.with_oneshot(false).with_shutdown(false))
210 .await?;
211 Ok(())
212 }
213
214 async fn stop_measuring(&mut self) -> Result<(), Self::Error> {
216 let reg_conf = self.read_register::<Configuration>().await?;
217 self.write_register(reg_conf.with_oneshot(false).with_shutdown(true))
218 .await?;
219 Ok(())
220 }
221
222 async fn measurement_interval_us(&mut self) -> Result<u32, Self::Error> {
224 let reg_conf = self.read_register::<Configuration>().await?;
225 let conversion_time_us = reg_conf.read_conversion_cycle_time().conversion_time_ms() * 1000;
226 Ok(conversion_time_us)
227 }
228
229 async fn current_measurement(&mut self) -> Result<Option<Self::Measurement>, Self::Error> {
231 let raw_temp = self.read_register::<Temperature>().await?.read_raw_temperature() as i32;
232 let reg_conf = self.read_register::<Configuration>().await?;
233 if reg_conf.read_extended() {
234 Ok(Some(Measurement {
235 temperature: ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 128.0),
236 }))
237 } else {
238 Ok(Some(Measurement {
239 temperature: ThermodynamicTemperature::new::<degree_celsius>(raw_temp as f64 / 256.0),
240 }))
241 }
242 }
243
244 async fn is_measurement_ready(&mut self) -> Result<bool, Self::Error> {
246 Ok(true)
247 }
248
249 async fn next_measurement(&mut self) -> Result<Self::Measurement, Self::Error> {
251 let interval = self.measurement_interval_us().await?;
252 self.delay.delay_us(interval).await;
253 self.current_measurement()
254 .await?
255 .ok_or_else(|| TransportError::Unexpected("measurement was not ready even though we expected it to be"))
256 }
257}