1use super::{
2 BusOperation, DelayNs, I2c, RegisterOperation, SensorOperation, SevenBitAddress, SpiDevice,
3 bisync, i2c, prelude::*, spi,
4};
5
6use core::fmt::Debug;
7use core::marker::PhantomData;
8
9#[bisync]
16pub struct Lps22df<B, T, S>
17where
18 B: BusOperation,
19 T: DelayNs,
20 S: SensorState,
21{
22 pub bus: B,
23 pub tim: T,
24 _state: PhantomData<S>,
25}
26
27#[bisync]
29#[derive(Debug)]
30pub enum Error<B> {
31 Bus(B), UnexpectedValue, }
34
35#[bisync]
36impl<B, T, S> Lps22df<B, T, S>
37where
38 B: BusOperation,
39 T: DelayNs,
40 S: SensorState,
41{
42 pub fn new_bus(bus: B, tim: T) -> Self {
44 Self {
45 bus,
46 tim,
47 _state: PhantomData,
48 }
49 }
50}
51
52#[bisync]
53impl<P, T> Lps22df<i2c::I2cBus<P>, T, OnState>
54where
55 P: I2c,
56 T: DelayNs,
57{
58 pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
60 let bus = i2c::I2cBus::new(i2c, address as SevenBitAddress);
62 Self {
63 bus,
64 tim,
65 _state: PhantomData,
66 }
67 }
68}
69
70#[bisync]
71impl<P, T> Lps22df<spi::SpiBus<P>, T, OnState>
72where
73 P: SpiDevice,
74 T: DelayNs,
75{
76 pub fn new_spi(spi: P, tim: T) -> Self {
78 let bus = spi::SpiBus::new(spi);
80 Self {
81 bus,
82 tim,
83 _state: PhantomData,
84 }
85 }
86}
87
88#[bisync]
89impl<B, T, S> SensorOperation for Lps22df<B, T, S>
90where
91 B: BusOperation,
92 T: DelayNs,
93 S: SensorState,
94{
95 type Error = Error<B::Error>;
96
97 #[inline]
98 async fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
99 self.bus
100 .read_from_register(reg, buf)
101 .await
102 .map_err(Error::Bus)
103 }
104
105 #[inline]
106 async fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
107 self.bus
108 .write_to_register(reg, buf)
109 .await
110 .map_err(Error::Bus)
111 }
112}
113
114#[bisync]
115impl<B: BusOperation, T: DelayNs> Lps22df<B, T, OnState> {
116 pub async fn id_get(&mut self) -> Result<u8, Error<B::Error>> {
121 WhoAmI::read(self).await.map(|reg| reg.id())
122 }
123 pub async fn bus_mode_set(&mut self, val: &BusMode) -> Result<(), Error<B::Error>> {
127 let mut if_ctrl = IfCtrl::read(self).await?;
128 if_ctrl.set_i2c_i3c_dis(((val.interface as u8) & 0x02) >> 1);
129 if_ctrl.set_int_en_i3c(((val.interface as u8) & 0x04) >> 2);
130 if_ctrl.set_sim((val.interface as u8) & 0x01);
131 if_ctrl.write(self).await?;
132
133 let mut i3c_if_ctrl = I3cIfCtrl::read(self).await?;
134 i3c_if_ctrl.set_asf_on((val.filter as u8) & 0x01);
135 i3c_if_ctrl.set_i3c_bus_avb_sel((val.i3c_ibi_time as u8) & 0x03);
136 i3c_if_ctrl.write(self).await?;
137
138 Ok(())
139 }
140 pub async fn bus_mode_get(&mut self) -> Result<BusMode, Error<B::Error>> {
145 let if_ctrl = IfCtrl::read(self).await?;
146 let i3c_if_ctrl = I3cIfCtrl::read(self).await?;
147
148 let interface = (if_ctrl.int_en_i3c() << 2) | (if_ctrl.i2c_i3c_dis() << 1) | if_ctrl.sim();
149 let interface = Interface::try_from(interface).unwrap_or(Interface::SelByHw);
150
151 let filter = Filter::try_from(i3c_if_ctrl.asf_on()).unwrap_or_default();
152
153 let i3c_ibi_time = i3c_if_ctrl.i3c_bus_avb_sel();
154 let i3c_ibi_time = I3cIbiTime::try_from(i3c_ibi_time).unwrap_or_default();
155
156 Ok(BusMode {
157 interface,
158 filter,
159 i3c_ibi_time,
160 })
161 }
162
163 pub async fn init_set(&mut self, val: Init) -> Result<(), Error<B::Error>> {
170 let mut reg: [u8; 2] = [0, 0];
172 self.read_from_register(Reg::CtrlReg2 as u8, &mut reg)
173 .await?;
174 let mut ctrl_reg2 = CtrlReg2::from_bits(reg[0]);
175 let mut ctrl_reg3 = CtrlReg3::from_bits(reg[1]);
176 let mut cnt: u8 = 0;
177
178 match val {
179 Init::Boot => {
180 ctrl_reg2.set_boot(1);
181 ctrl_reg2.write(self).await?;
182
183 loop {
184 let int_src = IntSource::read(self).await?;
185
186 if int_src.boot_on() == 0 {
187 break;
188 }
189
190 self.tim.delay_ms(10).await;
191
192 if cnt >= 5 {
193 return Err(Error::UnexpectedValue);
194 }
195
196 cnt += 1;
197 }
198 }
199 Init::Reset => {
200 ctrl_reg2.set_swreset(1);
201 self.write_to_register(Reg::CtrlReg2 as u8, &[ctrl_reg2.into()])
202 .await?;
203
204 loop {
205 let status = self.status_get().await?;
206 if status.sw_reset == 0 {
207 break;
208 }
209
210 self.tim.delay_ms(10).await;
211
212 if cnt >= 5 {
213 return Err(Error::UnexpectedValue);
214 }
215
216 cnt += 1;
217 }
218 }
219 Init::DrvRdy => {
220 ctrl_reg2.set_bdu(1);
221 ctrl_reg3.set_if_add_inc(1);
222 reg[0] = ctrl_reg2.into();
224 reg[1] = ctrl_reg3.into();
225 self.write_to_register(Reg::CtrlReg2 as u8, ®).await?;
226 }
227 }
228
229 Ok(())
230 }
231 pub async fn status_get(&mut self) -> Result<Stat, Error<B::Error>> {
241 let ctrl_reg2 = CtrlReg2::read(self).await?;
242 let int_source = IntSource::read(self).await?;
243 let status = Status::read(self).await?;
244 let interrupt_cfg = InterruptCfg::read(self).await?;
245
246 Ok(Stat {
247 sw_reset: ctrl_reg2.swreset(),
248 boot: int_source.boot_on(),
249 drdy_pres: status.p_da(),
250 drdy_temp: status.t_da(),
251 ovr_pres: status.p_or(),
252 ovr_temp: status.t_or(),
253 end_meas: !ctrl_reg2.oneshot(),
254 ref_done: !interrupt_cfg.autozero(),
255 })
256 }
257 pub async fn pin_conf_set(&mut self, val: &PinConf) -> Result<(), Error<B::Error>> {
263 let mut if_ctrl = IfCtrl::read(self).await?;
265
266 if_ctrl.set_int_pd_dis(!val.int_pull_down);
268 if_ctrl.set_sdo_pu_en(val.sdo_pull_up);
269 if_ctrl.set_sda_pu_en(val.sda_pull_up);
270 if_ctrl.set_cs_pu_dis(!val.cs_pull_up);
271
272 if_ctrl.write(self).await?;
274
275 let mut ctrl_reg3 = CtrlReg3::read(self).await?;
277
278 ctrl_reg3.set_pp_od(!val.int_push_pull);
280
281 ctrl_reg3.write(self).await?;
283
284 Ok(())
285 }
286 pub async fn pin_conf_get(&mut self) -> Result<PinConf, Error<B::Error>> {
290 let if_ctrl = IfCtrl::read(self).await?;
291 let ctrl_reg3 = CtrlReg3::read(self).await?;
292
293 let val = PinConf {
294 sda_pull_up: if_ctrl.sda_pu_en(),
295 cs_pull_up: !if_ctrl.cs_pu_dis(),
296 int_pull_down: !if_ctrl.int_pd_dis(),
297 sdo_pull_up: if_ctrl.sdo_pu_en(),
298 int_push_pull: !ctrl_reg3.pp_od(),
299 };
300
301 Ok(val)
302 }
303 pub async fn all_sources_get(&mut self) -> Result<AllSources, Error<B::Error>> {
308 let status = Status::read(self).await?;
309 let int_source = IntSource::read(self).await?;
310 let fifo_status2 = FifoStatus2::read(self).await?;
311
312 let val = AllSources {
313 drdy_pres: status.p_da(),
314 drdy_temp: status.t_da(),
315 over_pres: int_source.ph(),
316 under_pres: int_source.pl(),
317 thrsld_pres: int_source.ia(),
318 fifo_full: fifo_status2.fifo_full_ia(),
319 fifo_ovr: fifo_status2.fifo_ovr_ia(),
320 fifo_th: fifo_status2.fifo_wtm_ia(),
321 };
322
323 Ok(val)
324 }
325 pub async fn mode_set(&mut self, val: &Md) -> Result<(), Error<B::Error>> {
329 let mut ctrl_reg1 = CtrlReg1::read(self).await?;
330 let mut ctrl_reg2 = CtrlReg2::read(self).await?;
331
332 ctrl_reg1.set_odr(val.odr as u8);
333 ctrl_reg1.set_avg(val.avg as u8);
334 ctrl_reg2.set_en_lpfp(val.lpf as u8 & 0x01);
335 ctrl_reg2.set_lfpf_cfg((val.lpf as u8 & 0x02) >> 1);
336
337 ctrl_reg1.write(self).await?;
338 ctrl_reg2.write(self).await?;
339
340 Ok(())
341 }
342 pub async fn mode_get(&mut self) -> Result<Md, Error<B::Error>> {
346 let ctrl_reg1 = CtrlReg1::read(self).await?;
347 let ctrl_reg2 = CtrlReg2::read(self).await?;
348
349 let odr = Odr::try_from(ctrl_reg1.odr()).unwrap_or_default();
350 let avg = Avg::try_from(ctrl_reg1.avg()).unwrap_or_default();
351 let lpf = (ctrl_reg2.lfpf_cfg() << 2) | ctrl_reg2.en_lpfp();
352 let lpf = LowPassFilter::try_from(lpf).unwrap_or_default();
353
354 Ok(Md { odr, avg, lpf })
355 }
356 pub async fn trigger_sw(&mut self, md: &Md) -> Result<(), Error<B::Error>> {
360 if md.odr == Odr::OneShot {
361 let mut ctrl_reg2 = CtrlReg2::read(self).await?;
362 ctrl_reg2.set_oneshot(1);
363 ctrl_reg2.write(self).await?;
364 }
365 Ok(())
366 }
367 pub async fn data_get(&mut self) -> Result<Data, Error<B::Error>> {
371 let raw_pressure = PressOut::read(self).await?.pressure();
373 let pressure_hpa = from_lsb_to_hpa(raw_pressure);
374
375 let raw_heat: i16 = TempOut::read(self).await?.temp_c();
377 let heat_deg_c = from_lsb_to_celsius(raw_heat);
378
379 let data = Data {
381 pressure: Pressure {
382 hpa: pressure_hpa,
383 raw: raw_pressure,
384 },
385 heat: Heat {
386 deg_c: heat_deg_c,
387 raw: raw_heat,
388 },
389 };
390
391 Ok(data)
392 }
393
394 pub async fn pressure_raw_get(&mut self) -> Result<u32, Error<B::Error>> {
398 Ok(PressOut::read(self).await?.into_bits())
399 }
400 pub async fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
404 TempOut::read(self).await.map(|reg| reg.temp_c())
405 }
406 pub async fn fifo_mode_set(&mut self, op: Operation) -> Result<(), Error<B::Error>> {
411 let mut fifo_ctrl = FifoCtrl::read(self).await?;
412
413 fifo_ctrl.set_f_mode((op as u8) & 0x03);
414 fifo_ctrl.set_trig_modes(((op as u8) & 0x04) >> 2);
415
416 fifo_ctrl.write(self).await
417 }
418 pub async fn fifo_mode_get(&mut self) -> Result<Operation, Error<B::Error>> {
423 let fifo_ctrl = FifoCtrl::read(self).await?;
424
425 let operation = (fifo_ctrl.trig_modes() << 2) | fifo_ctrl.f_mode();
426 Ok(Operation::try_from(operation).unwrap_or_default())
427 }
428
429 pub async fn fifo_watermark_set(&mut self, watermark: u8) -> Result<(), Error<B::Error>> {
453 assert!(watermark < 128);
454
455 let mut fifo_wtm = FifoWtm::read(self).await?;
456 fifo_wtm.set_wtm(watermark);
457 fifo_wtm.write(self).await
458 }
459
460 pub async fn fifo_watermark_get(&mut self) -> Result<u8, Error<B::Error>> {
477 let fifo_wtm = FifoWtm::read(self).await?;
478 Ok(fifo_wtm.wtm())
479 }
480
481 pub async fn fifo_stop_on_wtm_set(&mut self, fth: FifoEvent) -> Result<(), Error<B::Error>> {
499 let mut fifo_ctrl = FifoCtrl::read(self).await?;
500 fifo_ctrl.set_stop_on_wtm(fth as u8);
501 fifo_ctrl.write(self).await
502 }
503
504 pub async fn fifo_stop_on_wtm_get(&mut self) -> Result<FifoEvent, Error<B::Error>> {
520 let ctrl = FifoCtrl::read(self).await?;
521 let evt = FifoEvent::try_from(ctrl.stop_on_wtm()).unwrap_or_default();
522 Ok(evt)
523 }
524
525 pub async fn fifo_level_get(&mut self) -> Result<u8, Error<B::Error>> {
529 let val: u8 = FifoStatus1::read(self).await?.fss();
530
531 Ok(val)
532 }
533 pub async fn fifo_data_get(&mut self, samp: u8) -> Result<[FifoData; 32], Error<B::Error>> {
538 let mut data: [FifoData; 32] = [FifoData { raw: 0, hpa: 0.0 }; 32];
539 for item in data.iter_mut().take(samp as usize) {
540 let raw: i32 = FifoDataOutPress::read(self).await?.pressure();
541 let hpa = from_lsb_to_hpa(raw);
542
543 *item = FifoData { raw, hpa };
544 }
545
546 Ok(data)
547 }
548 pub async fn interrupt_mode_set(&mut self, val: &IntMode) -> Result<(), Error<B::Error>> {
553 let mut ctrl_reg3 = CtrlReg3::read(self).await?;
554 let mut ctrl_reg4 = CtrlReg4::read(self).await?;
555 ctrl_reg3.set_int_h_l(val.active_low);
556 ctrl_reg4.set_drdy_pls(!val.drdy_latched);
557 ctrl_reg3.write(self).await?;
558 ctrl_reg4.write(self).await?;
559
560 let mut interrupt_cfg = InterruptCfg::read(self).await?;
561 interrupt_cfg.set_lir(val.int_latched);
562 interrupt_cfg.write(self).await?;
563
564 Ok(())
565 }
566 pub async fn interrupt_mode_get(&mut self) -> Result<IntMode, Error<B::Error>> {
571 let interrupt_cfg = InterruptCfg::read(self).await?;
572 let ctrl_reg3 = CtrlReg3::read(self).await?;
573 let ctrl_reg4 = CtrlReg4::read(self).await?;
574
575 let active_low = ctrl_reg3.int_h_l();
576 let drdy_latched = !ctrl_reg4.drdy_pls();
577 let int_latched = interrupt_cfg.lir();
578
579 Ok(IntMode {
580 active_low,
581 drdy_latched,
582 int_latched,
583 })
584 }
585 pub async fn pin_int_route_set(&mut self, val: &PinIntRoute) -> Result<(), Error<B::Error>> {
589 let mut ctrl_reg4 = CtrlReg4::read(self).await?;
590 ctrl_reg4.set_drdy(val.drdy_pres);
591 ctrl_reg4.set_int_f_wtm(val.fifo_th);
592 ctrl_reg4.set_int_f_ovr(val.fifo_ovr);
593 ctrl_reg4.set_int_f_full(val.fifo_full);
594 ctrl_reg4.write(self).await?;
595
596 Ok(())
597 }
598 pub async fn pin_int_route_get(&mut self) -> Result<PinIntRoute, Error<B::Error>> {
602 let reg = CtrlReg4::read(self).await?;
603
604 let val = PinIntRoute {
605 drdy_pres: reg.drdy(),
606 fifo_th: reg.int_f_wtm(),
607 fifo_ovr: reg.int_f_ovr(),
608 fifo_full: reg.int_f_full(),
609 };
610
611 Ok(val)
612 }
613 pub async fn int_on_threshold_mode_set(
619 &mut self,
620 val: &IntThMd,
621 ) -> Result<(), Error<B::Error>> {
622 let mut interrupt_cfg = InterruptCfg::read(self).await?;
623 let mut ths_p = ThsP::read(self).await?;
624
625 interrupt_cfg.set_phe(val.over_th);
626 interrupt_cfg.set_ple(val.under_th);
627 ths_p.set_ths(val.threshold);
628
629 interrupt_cfg.write(self).await?;
630 ths_p.write(self).await?;
631
632 let mut ctrl_reg4 = CtrlReg4::read(self).await?;
633 ctrl_reg4.set_int_en(1);
634 ctrl_reg4.write(self).await?;
635
636 Ok(())
637 }
638 pub async fn int_on_threshold_mode_get(&mut self) -> Result<IntThMd, Error<B::Error>> {
643 let interrupt_cfg = InterruptCfg::read(self).await?;
644 let ths_p = ThsP::read(self).await?;
645
646 let over_th = interrupt_cfg.phe();
647 let under_th = interrupt_cfg.ple();
648 let threshold: u16 = ths_p.ths();
649 Ok(IntThMd {
650 over_th,
651 under_th,
652 threshold,
653 })
654 }
655 pub async fn reference_mode_set(&mut self, val: &RefMd) -> Result<(), Error<B::Error>> {
661 let mut interrupt_cfg = InterruptCfg::read(self).await?;
662
663 interrupt_cfg.set_autozero(val.get_ref);
664 interrupt_cfg.set_autorefp((val.apply_ref as u8) & 0x01);
665 interrupt_cfg.set_reset_az(((val.apply_ref as u8) & 0x02) >> 1);
666 interrupt_cfg.set_reset_arp(((val.apply_ref as u8) & 0x02) >> 1);
667
668 interrupt_cfg.write(self).await?;
669
670 Ok(())
671 }
672 pub async fn reference_mode_get(&mut self) -> Result<RefMd, Error<B::Error>> {
677 let interrupt_cfg = InterruptCfg::read(self).await?;
678 let apply_ref = (interrupt_cfg.reset_az() << 1) | interrupt_cfg.autorefp();
679 let apply_ref = ApplyRef::try_from(apply_ref).unwrap_or(ApplyRef::RstRefs);
680 let get_ref = interrupt_cfg.autozero();
681
682 Ok(RefMd { apply_ref, get_ref })
683 }
684 pub async fn opc_set(&mut self, val: i16) -> Result<(), Error<B::Error>> {
689 Rpds::new().with_offset(val).write(self).await
690 }
691 pub async fn opc_get(&mut self) -> Result<i16, Error<B::Error>> {
695 Rpds::read(self).await.map(|reg| reg.offset())
696 }
697}
698
699#[bisync]
700pub fn from_lsb_to_hpa(lsb: i32) -> f32 {
701 (lsb as f32) / 1048576.0
702}
703
704#[bisync]
705pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
706 (lsb as f32) / 100.0
707}
708
709#[repr(u8)]
711#[derive(Clone, Copy, PartialEq)]
712#[bisync]
713pub enum I2CAddress {
714 I2cAddL = 0x5C,
716 I2cAddH = 0x5D,
718}
719
720#[bisync]
721pub const ID: u8 = 0xB4;