1#![no_std]
2#![doc = include_str!("../README.md")]
3use core::fmt::Debug;
4use embedded_hal::delay::DelayNs;
5use embedded_hal::i2c::{I2c, SevenBitAddress};
6use embedded_hal::spi::SpiDevice;
7use st_mems_bus::*;
8
9pub mod prelude;
10pub mod register;
11
12use prelude::*;
13
14pub struct Lps22df<B, T> {
21 pub bus: B,
22 pub tim: T,
23}
24
25#[derive(Debug)]
27pub enum Error<B> {
28 Bus(B), UnexpectedValue, }
31impl<B, T> Lps22df<B, T>
32where
33 B: BusOperation,
34 T: DelayNs,
35{
36 pub fn new_bus(bus: B, tim: T) -> Self {
38 Self { bus, tim }
39 }
40}
41impl<P, T> Lps22df<i2c::I2cBus<P>, T>
42where
43 P: I2c,
44 T: DelayNs,
45{
46 pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
48 let bus = i2c::I2cBus::new(i2c, address as SevenBitAddress);
50 Self { bus, tim }
51 }
52}
53impl<P, T> Lps22df<spi::SpiBus<P>, T>
54where
55 P: SpiDevice,
56 T: DelayNs,
57{
58 pub fn new_spi(spi: P, tim: T) -> Self {
60 let bus = spi::SpiBus::new(spi);
62 Self { bus, tim }
63 }
64}
65
66impl<B: BusOperation, T: DelayNs> Lps22df<B, T> {
67 #[inline]
68 pub fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
69 self.bus.read_from_register(reg, buf).map_err(Error::Bus)
70 }
71
72 #[inline]
73 pub fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
74 self.bus.write_to_register(reg, buf).map_err(Error::Bus)
75 }
76
77 pub fn id_get(&mut self) -> Result<u8, Error<B::Error>> {
82 WhoAmI::read(self).map(|reg| reg.id())
83 }
84 pub fn bus_mode_set(&mut self, val: &BusMode) -> Result<(), Error<B::Error>> {
88 let mut if_ctrl = IfCtrl::read(self)?;
89 if_ctrl.set_i2c_i3c_dis(((val.interface as u8) & 0x02) >> 1);
90 if_ctrl.set_int_en_i3c(((val.interface as u8) & 0x04) >> 2);
91 if_ctrl.set_sim((val.interface as u8) & 0x01);
92 if_ctrl.write(self)?;
93
94 let mut i3c_if_ctrl = I3cIfCtrl::read(self)?;
95 i3c_if_ctrl.set_asf_on((val.filter as u8) & 0x01);
96 i3c_if_ctrl.set_i3c_bus_avb_sel((val.i3c_ibi_time as u8) & 0x03);
97 i3c_if_ctrl.write(self)?;
98
99 Ok(())
100 }
101 pub fn bus_mode_get(&mut self) -> Result<BusMode, Error<B::Error>> {
106 let if_ctrl = IfCtrl::read(self)?;
107 let i3c_if_ctrl = I3cIfCtrl::read(self)?;
108
109 let interface = (if_ctrl.int_en_i3c() << 2) | (if_ctrl.i2c_i3c_dis() << 1) | if_ctrl.sim();
110 let interface = Interface::try_from(interface).unwrap_or(Interface::SelByHw);
111
112 let filter = Filter::try_from(i3c_if_ctrl.asf_on()).unwrap_or_default();
113
114 let i3c_ibi_time = i3c_if_ctrl.i3c_bus_avb_sel();
115 let i3c_ibi_time = I3cIbiTime::try_from(i3c_ibi_time).unwrap_or_default();
116
117 Ok(BusMode {
118 interface,
119 filter,
120 i3c_ibi_time,
121 })
122 }
123
124 pub fn init_set(&mut self, val: Init) -> Result<(), Error<B::Error>> {
131 let mut reg: [u8; 2] = [0, 0];
133 self.read_from_register(Reg::CtrlReg2 as u8, &mut reg)?;
134 let mut ctrl_reg2 = CtrlReg2::from_bits(reg[0]);
135 let mut ctrl_reg3 = CtrlReg3::from_bits(reg[1]);
136 let mut cnt: u8 = 0;
137
138 match val {
139 Init::Boot => {
140 ctrl_reg2.set_boot(1);
141 ctrl_reg2.write(self)?;
142
143 loop {
144 let mut read_buffer: [u8; 1] = [0];
145 self.read_from_register(Reg::IntSource as u8, &mut read_buffer)?;
146 let int_src = IntSource::from_bits(read_buffer[0]);
147
148 if int_src.boot_on() == 0 {
149 break;
150 }
151
152 if cnt >= 5 {
155 return Err(Error::UnexpectedValue);
156 }
157
158 cnt += 1;
159 }
160 }
161 Init::Reset => {
162 ctrl_reg2.set_swreset(1);
163 self.write_to_register(Reg::CtrlReg2 as u8, &[ctrl_reg2.into()])?;
164
165 loop {
166 let status = self.status_get()?;
167 if status.sw_reset == 0 {
168 break;
169 }
170
171 if cnt >= 5 {
174 return Err(Error::UnexpectedValue);
175 }
176
177 cnt += 1;
178 }
179 }
180 Init::DrvRdy => {
181 ctrl_reg2.set_bdu(1);
182 ctrl_reg3.set_if_add_inc(1);
183 reg[0] = ctrl_reg2.into();
185 reg[1] = ctrl_reg3.into();
186 self.write_to_register(Reg::CtrlReg2 as u8, ®)?;
187 }
188 }
189
190 Ok(())
191 }
192 pub fn status_get(&mut self) -> Result<Stat, Error<B::Error>> {
202 let ctrl_reg2 = CtrlReg2::read(self)?;
203 let int_source = IntSource::read(self)?;
204 let status = Status::read(self)?;
205 let interrupt_cfg = InterruptCfg::read(self)?;
206
207 Ok(Stat {
208 sw_reset: ctrl_reg2.swreset(),
209 boot: int_source.boot_on(),
210 drdy_pres: status.p_da(),
211 drdy_temp: status.t_da(),
212 ovr_pres: status.p_or(),
213 ovr_temp: status.t_or(),
214 end_meas: !ctrl_reg2.oneshot(),
215 ref_done: !interrupt_cfg.autozero(),
216 })
217 }
218 pub fn pin_conf_set(&mut self, val: &PinConf) -> Result<(), Error<B::Error>> {
224 let mut if_ctrl = IfCtrl::read(self)?;
226
227 if_ctrl.set_int_pd_dis(!val.int_pull_down);
229 if_ctrl.set_sdo_pu_en(val.sdo_pull_up);
230 if_ctrl.set_sda_pu_en(val.sda_pull_up);
231 if_ctrl.set_cs_pu_dis(!val.cs_pull_up);
232
233 if_ctrl.write(self)?;
235
236 let mut ctrl_reg3 = CtrlReg3::read(self)?;
238
239 ctrl_reg3.set_pp_od(!val.int_push_pull);
241
242 ctrl_reg3.write(self)?;
244
245 Ok(())
246 }
247 pub fn pin_conf_get(&mut self) -> Result<PinConf, Error<B::Error>> {
251 let if_ctrl = IfCtrl::read(self)?;
252 let ctrl_reg3 = CtrlReg3::read(self)?;
253
254 let val = PinConf {
255 sda_pull_up: if_ctrl.sda_pu_en(),
256 cs_pull_up: !if_ctrl.cs_pu_dis(),
257 int_pull_down: !if_ctrl.int_pd_dis(),
258 sdo_pull_up: if_ctrl.sdo_pu_en(),
259 int_push_pull: !ctrl_reg3.pp_od(),
260 };
261
262 Ok(val)
263 }
264 pub fn all_sources_get(&mut self) -> Result<AllSources, Error<B::Error>> {
269 let status = Status::read(self)?;
270 let int_source = IntSource::read(self)?;
271 let fifo_status2 = FifoStatus2::read(self)?;
272
273 let val = AllSources {
274 drdy_pres: status.p_da(),
275 drdy_temp: status.t_da(),
276 over_pres: int_source.ph(),
277 under_pres: int_source.pl(),
278 thrsld_pres: int_source.ia(),
279 fifo_full: fifo_status2.fifo_full_ia(),
280 fifo_ovr: fifo_status2.fifo_ovr_ia(),
281 fifo_th: fifo_status2.fifo_wtm_ia(),
282 };
283
284 Ok(val)
285 }
286 pub fn mode_set(&mut self, val: &Md) -> Result<(), Error<B::Error>> {
290 let mut ctrl_reg1 = CtrlReg1::read(self)?;
291 let mut ctrl_reg2 = CtrlReg2::read(self)?;
292
293 ctrl_reg1.set_odr(val.odr as u8);
294 ctrl_reg1.set_avg(val.avg as u8);
295 ctrl_reg2.set_en_lpfp(val.lpf as u8 & 0x01);
296 ctrl_reg2.set_lfpf_cfg((val.lpf as u8 & 0x02) >> 1);
297
298 ctrl_reg1.write(self)?;
299 ctrl_reg2.write(self)?;
300
301 Ok(())
302 }
303 pub fn mode_get(&mut self) -> Result<Md, Error<B::Error>> {
307 let ctrl_reg1 = CtrlReg1::read(self)?;
308 let ctrl_reg2 = CtrlReg2::read(self)?;
309
310 let odr = Odr::try_from(ctrl_reg1.odr()).unwrap_or_default();
311 let avg = Avg::try_from(ctrl_reg1.avg()).unwrap_or_default();
312 let lpf = (ctrl_reg2.lfpf_cfg() << 2) | ctrl_reg2.en_lpfp();
313 let lpf = LowPassFilter::try_from(lpf).unwrap_or_default();
314
315 Ok(Md { odr, avg, lpf })
316 }
317 pub fn trigger_sw(&mut self, md: &Md) -> Result<(), Error<B::Error>> {
321 if md.odr == Odr::OneShot {
322 let mut ctrl_reg2 = CtrlReg2::read(self)?;
323 ctrl_reg2.set_oneshot(1);
324 ctrl_reg2.write(self)?;
325 }
326 Ok(())
327 }
328 pub fn data_get(&mut self) -> Result<Data, Error<B::Error>> {
332 let raw_pressure = PressOut::read(self)?.pressure();
334 let pressure_hpa = from_lsb_to_hpa(raw_pressure);
335
336 let raw_heat: i16 = TempOut::read(self)?.temp_c();
338 let heat_deg_c = from_lsb_to_celsius(raw_heat);
339
340 let data = Data {
342 pressure: Pressure {
343 hpa: pressure_hpa,
344 raw: raw_pressure,
345 },
346 heat: Heat {
347 deg_c: heat_deg_c,
348 raw: raw_heat,
349 },
350 };
351
352 Ok(data)
353 }
354
355 pub fn pressure_raw_get(&mut self) -> Result<u32, Error<B::Error>> {
359 Ok(PressOut::read(self)?.into_bits())
360 }
361 pub fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
365 TempOut::read(self).map(|reg| reg.temp_c())
366 }
367 pub fn fifo_mode_set(&mut self, val: &FifoMd) -> Result<(), Error<B::Error>> {
373 let mut fifo_ctrl = FifoCtrl::read(self)?;
374 let mut fifo_wtm = FifoWtm::read(self)?;
375
376 fifo_ctrl.set_f_mode((val.operation as u8) & 0x03);
377 fifo_ctrl.set_trig_modes(((val.operation as u8) & 0x04) >> 2);
378
379 let stop_on_wtm = if val.watermark != 0 { 1 } else { 0 };
380 fifo_ctrl.set_stop_on_wtm(stop_on_wtm);
381 fifo_wtm.set_wtm(val.watermark);
382
383 fifo_ctrl.write(self)?;
384 fifo_wtm.write(self)?;
385
386 Ok(())
387 }
388 pub fn fifo_mode_get(&mut self) -> Result<FifoMd, Error<B::Error>> {
393 let fifo_ctrl = FifoCtrl::read(self)?;
394 let fifo_wtm = FifoWtm::read(self)?;
395
396 let operation = (fifo_ctrl.trig_modes() << 2) | fifo_ctrl.f_mode();
397 let operation = Operation::try_from(operation).unwrap_or_default();
398 Ok(FifoMd {
399 operation,
400 watermark: fifo_wtm.wtm(),
401 })
402 }
403 pub fn fifo_level_get(&mut self) -> Result<u8, Error<B::Error>> {
407 let val: u8 = FifoStatus1::read(self)?.fss();
408
409 Ok(val)
410 }
411 pub fn fifo_data_get(&mut self, samp: u8) -> Result<[FifoData; 32], Error<B::Error>> {
416 let mut data: [FifoData; 32] = [FifoData { raw: 0, hpa: 0.0 }; 32];
417 for item in data.iter_mut().take(samp as usize) {
418 let raw: i32 = FifoDataOutPress::read(self)?.pressure();
419 let hpa = from_lsb_to_hpa(raw);
420
421 *item = FifoData { raw, hpa };
422 }
423
424 Ok(data)
425 }
426 pub fn interrupt_mode_set(&mut self, val: &IntMode) -> Result<(), Error<B::Error>> {
431 let mut ctrl_reg3 = CtrlReg3::read(self)?;
432 let mut ctrl_reg4 = CtrlReg4::read(self)?;
433 ctrl_reg3.set_int_h_l(val.active_low);
434 ctrl_reg4.set_drdy_pls(!val.drdy_latched);
435 ctrl_reg3.write(self)?;
436 ctrl_reg4.write(self)?;
437
438 let mut interrupt_cfg = InterruptCfg::read(self)?;
439 interrupt_cfg.set_lir(val.int_latched);
440 interrupt_cfg.write(self)?;
441
442 Ok(())
443 }
444 pub fn interrupt_mode_get(&mut self) -> Result<IntMode, Error<B::Error>> {
449 let interrupt_cfg = InterruptCfg::read(self)?;
450 let ctrl_reg3 = CtrlReg3::read(self)?;
451 let ctrl_reg4 = CtrlReg4::read(self)?;
452
453 let active_low = ctrl_reg3.int_h_l();
454 let drdy_latched = !ctrl_reg4.drdy_pls();
455 let int_latched = interrupt_cfg.lir();
456
457 Ok(IntMode {
458 active_low,
459 drdy_latched,
460 int_latched,
461 })
462 }
463 pub fn pin_int_route_set(&mut self, val: &PinIntRoute) -> Result<(), Error<B::Error>> {
467 let mut ctrl_reg4 = CtrlReg4::read(self)?;
468 ctrl_reg4.set_drdy(val.drdy_pres);
469 ctrl_reg4.set_int_f_wtm(val.fifo_th);
470 ctrl_reg4.set_int_f_ovr(val.fifo_ovr);
471 ctrl_reg4.set_int_f_full(val.fifo_full);
472 ctrl_reg4.write(self)?;
473
474 Ok(())
475 }
476 pub fn pin_int_route_get(&mut self) -> Result<PinIntRoute, Error<B::Error>> {
480 let reg = CtrlReg4::read(self)?;
481
482 let val = PinIntRoute {
483 drdy_pres: reg.drdy(),
484 fifo_th: reg.int_f_wtm(),
485 fifo_ovr: reg.int_f_ovr(),
486 fifo_full: reg.int_f_full(),
487 };
488
489 Ok(val)
490 }
491 pub fn int_on_threshold_mode_set(&mut self, val: &IntThMd) -> Result<(), Error<B::Error>> {
497 let mut interrupt_cfg = InterruptCfg::read(self)?;
498 let mut ths_p = ThsP::read(self)?;
499
500 interrupt_cfg.set_phe(val.over_th);
501 interrupt_cfg.set_ple(val.under_th);
502 ths_p.set_ths(val.threshold);
503
504 interrupt_cfg.write(self)?;
505 ths_p.write(self)?;
506
507 let mut ctrl_reg4 = CtrlReg4::read(self)?;
508 ctrl_reg4.set_int_en(1);
509 ctrl_reg4.write(self)?;
510
511 Ok(())
512 }
513 pub fn int_on_threshold_mode_get(&mut self) -> Result<IntThMd, Error<B::Error>> {
518 let interrupt_cfg = InterruptCfg::read(self)?;
519 let ths_p = ThsP::read(self)?;
520
521 let over_th = interrupt_cfg.phe();
522 let under_th = interrupt_cfg.ple();
523 let threshold: u16 = ths_p.ths();
524 Ok(IntThMd {
525 over_th,
526 under_th,
527 threshold,
528 })
529 }
530 pub fn reference_mode_set(&mut self, val: &RefMd) -> Result<(), Error<B::Error>> {
536 let mut interrupt_cfg = InterruptCfg::read(self)?;
537
538 interrupt_cfg.set_autozero(val.get_ref);
539 interrupt_cfg.set_autorefp((val.apply_ref as u8) & 0x01);
540 interrupt_cfg.set_reset_az(((val.apply_ref as u8) & 0x02) >> 1);
541 interrupt_cfg.set_reset_arp(((val.apply_ref as u8) & 0x02) >> 1);
542
543 interrupt_cfg.write(self)?;
544
545 Ok(())
546 }
547 pub fn reference_mode_get(&mut self) -> Result<RefMd, Error<B::Error>> {
552 let interrupt_cfg = InterruptCfg::read(self)?;
553 let apply_ref = (interrupt_cfg.reset_az() << 1) | interrupt_cfg.autorefp();
554 let apply_ref = ApplyRef::try_from(apply_ref).unwrap_or(ApplyRef::RstRefs);
555 let get_ref = interrupt_cfg.autozero();
556
557 Ok(RefMd { apply_ref, get_ref })
558 }
559 pub fn opc_set(&mut self, val: i16) -> Result<(), Error<B::Error>> {
564 Rpds::new().with_offset(val).write(self)
565 }
566 pub fn opc_get(&mut self) -> Result<i16, Error<B::Error>> {
570 Rpds::read(self).map(|reg| reg.offset())
571 }
572}
573
574pub fn from_lsb_to_hpa(lsb: i32) -> f32 {
575 (lsb as f32) / 1048576.0
576}
577pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
578 (lsb as f32) / 100.0
579}
580
581#[repr(u8)]
583#[derive(Clone, Copy, PartialEq)]
584pub enum I2CAddress {
585 I2cAddL = 0x5C,
587 I2cAddH = 0x5D,
589}
590
591pub const ID: u8 = 0xB4;