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 Lis2mdl<B, T, S>
17where
18 B: BusOperation,
19 T: DelayNs,
20 S: SensorState,
21{
22 pub bus: B,
24 pub tim: T,
25 _state: PhantomData<S>,
26}
27
28#[derive(Debug)]
30#[bisync]
31pub enum Error<B> {
32 Bus(B), UnexpectedValue, InvalidConfiguration,
35 HwNoResponse,
36}
37
38#[bisync]
39impl<B, T, S> Lis2mdl<B, T, S>
40where
41 B: BusOperation,
42 T: DelayNs,
43 S: SensorState,
44{
45 pub fn new_bus(bus: B, tim: T) -> Self {
47 Self {
48 bus,
49 tim,
50 _state: PhantomData,
51 }
52 }
53}
54
55#[bisync]
56impl<P, T> Lis2mdl<i2c::I2cBus<P>, T, OnState>
57where
58 P: I2c,
59 T: DelayNs,
60{
61 pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
63 let bus = i2c::I2cBus::new(i2c, address as SevenBitAddress);
65 Self {
66 bus,
67 tim,
68 _state: PhantomData,
69 }
70 }
71}
72
73#[bisync]
74impl<P, T, S> Lis2mdl<spi::SpiBus<P>, T, S>
75where
76 P: SpiDevice,
77 T: DelayNs,
78 S: SensorState,
79{
80 pub fn new_spi(spi: P, tim: T) -> Self {
82 let bus = spi::SpiBus::new(spi);
84 Self {
85 bus,
86 tim,
87 _state: PhantomData,
88 }
89 }
90}
91
92#[bisync]
93impl<B, T, S> SensorOperation for Lis2mdl<B, T, S>
94where
95 B: BusOperation,
96 T: DelayNs,
97 S: SensorState,
98{
99 type Error = Error<B::Error>;
100
101 async fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
102 self.bus
103 .write_to_register(reg, buf)
104 .await
105 .map_err(Error::Bus)
106 }
107
108 async fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
109 self.bus
110 .read_from_register(reg, buf)
111 .await
112 .map_err(Error::Bus)
113 }
114}
115
116#[bisync]
117impl<B, T> Lis2mdl<B, T, OnState>
118where
119 B: BusOperation,
120 T: DelayNs,
121{
122 pub async fn mag_user_offset_set(&mut self, val: &[i16; 3]) -> Result<(), Error<B::Error>> {
128 let offset = OffsetXYZ {
129 x: val[0],
130 y: val[1],
131 z: val[2],
132 };
133 offset.write(self).await?;
134
135 Ok(())
136 }
137
138 pub async fn mag_user_offset_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
144 let val = OffsetXYZ::read(self).await?;
145
146 Ok([val.x, val.y, val.z])
147 }
148
149 pub async fn operating_mode_set(&mut self, val: Md) -> Result<(), Error<B::Error>> {
151 let mut reg = CfgRegA::read(self).await?;
152 reg.set_md(val as u8);
153 reg.write(self).await
154 }
155 pub async fn operating_mode_get(&mut self) -> Result<Md, Error<B::Error>> {
157 let reg = CfgRegA::read(self).await?;
158
159 let val = Md::try_from(reg.md()).unwrap_or_default();
160 Ok(val)
161 }
162 pub async fn data_rate_set(&mut self, val: Odr) -> Result<(), Error<B::Error>> {
164 let mut reg = CfgRegA::read(self).await?;
165 reg.set_odr(val as u8);
166 reg.write(self).await
167 }
168 pub async fn data_rate_get(&mut self) -> Result<Odr, Error<B::Error>> {
170 let reg = CfgRegA::read(self).await?;
171 let val = Odr::try_from(reg.odr()).unwrap_or_default();
172 Ok(val)
173 }
174 pub async fn power_mode_set(&mut self, val: PowerMode) -> Result<(), Error<B::Error>> {
176 let mut reg = CfgRegA::read(self).await?;
177 reg.set_lp(val as u8);
178 reg.write(self).await?;
179
180 Ok(())
181 }
182 pub async fn power_mode_get(&mut self) -> Result<PowerMode, Error<B::Error>> {
184 let reg = CfgRegA::read(self).await?;
185
186 let val = PowerMode::try_from(reg.lp()).unwrap_or_default();
187 Ok(val)
188 }
189 pub async fn offset_temp_comp_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
191 let mut reg = CfgRegA::read(self).await?;
192 reg.set_comp_temp_en(val);
193 reg.write(self).await?;
194
195 Ok(())
196 }
197 pub async fn offset_temp_comp_get(&mut self) -> Result<u8, Error<B::Error>> {
199 let val: u8 = CfgRegA::read(self).await?.comp_temp_en();
200
201 Ok(val)
202 }
203 pub async fn low_pass_bandwidth_set(
205 &mut self,
206 val: LowPassFilter,
207 ) -> Result<(), Error<B::Error>> {
208 let mut reg = CfgRegB::read(self).await?;
209 reg.set_lpf(val as u8);
210 reg.write(self).await?;
211
212 Ok(())
213 }
214 pub async fn low_pass_bandwidth_get(&mut self) -> Result<LowPassFilter, Error<B::Error>> {
216 let reg = CfgRegB::read(self).await?;
217
218 let val = LowPassFilter::try_from(reg.lpf()).unwrap_or_default();
219 Ok(val)
220 }
221 pub async fn set_rst_mode_set(&mut self, val: SetRst) -> Result<(), Error<B::Error>> {
223 let mut reg = CfgRegB::read(self).await?;
224 reg.set_set_rst(val as u8);
225 reg.write(self).await?;
226
227 Ok(())
228 }
229 pub async fn set_rst_mode_get(&mut self) -> Result<SetRst, Error<B::Error>> {
231 let reg = CfgRegB::read(self).await?;
232
233 let val = SetRst::try_from(reg.set_rst()).unwrap_or_default();
234 Ok(val)
235 }
236 pub async fn set_rst_sensor_single_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
243 let mut reg = CfgRegB::read(self).await?;
244 let rst = SetRst::try_from(reg.set_rst()).map_err(|_| Error::UnexpectedValue)?;
245
246 if val == 1 && rst != SetRst::SensOffCancEveryOdr {
247 return Err(Error::InvalidConfiguration);
248 }
249
250 reg.set_off_canc_one_shot(val);
251 reg.write(self).await?;
252
253 Ok(())
254 }
255 pub async fn set_rst_sensor_single_get(&mut self) -> Result<u8, Error<B::Error>> {
261 let val: u8 = CfgRegB::read(self).await?.off_canc_one_shot();
262
263 Ok(val)
264 }
265 pub async fn block_data_update_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
269 let mut reg = CfgRegC::read(self).await?;
270 reg.set_bdu(val);
271 reg.write(self).await?;
272
273 Ok(())
274 }
275 pub async fn block_data_update_get(&mut self) -> Result<u8, Error<B::Error>> {
277 let val: u8 = CfgRegC::read(self).await?.bdu();
278
279 Ok(val)
280 }
281 pub async fn mag_data_ready_get(&mut self) -> Result<u8, Error<B::Error>> {
285 let val: u8 = StatusReg::read(self).await?.zyxda();
286
287 Ok(val)
288 }
289 pub async fn mag_data_ovr_get(&mut self) -> Result<u8, Error<B::Error>> {
293 let val: u8 = StatusReg::read(self).await?.zyxor();
294
295 Ok(val)
296 }
297 pub async fn magnetic_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
301 let val = OutXYZ::read(self).await?;
302
303 Ok([val.x, val.y, val.z])
304 }
305
306 pub async fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
308 TempOut::read(self).await.map(|temp| temp.0)
309 }
310
311 pub async fn device_id_get(&mut self) -> Result<u8, Error<B::Error>> {
315 WhoAmI::read(self).await.map(|reg| reg.who_am_i())
316 }
317
318 pub async fn sw_reset(&mut self) -> Result<(), Error<B::Error>> {
326 let mut cfg_reg_a = CfgRegA::default();
327 let mut retry: u8 = 0;
328
329 cfg_reg_a.set_soft_rst(1);
331 cfg_reg_a.write(self).await?;
332
333 loop {
335 cfg_reg_a = CfgRegA::read(self).await?;
336
337 if cfg_reg_a.soft_rst() == 0 {
338 return Ok(());
339 }
340
341 retry += 1;
342 if retry > 3 {
343 break;
344 }
345
346 self.tim.delay_us(5).await;
347 }
348
349 Err(Error::HwNoResponse)
350 }
351
352 #[deprecated(since = "2.0.0", note = "please use sw_reset")]
357 pub async fn reset_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
358 let mut reg = CfgRegA::read(self).await?;
359 reg.set_soft_rst(val);
360 reg.write(self).await?;
361
362 Ok(())
363 }
364 #[deprecated(since = "2.0.0", note = "please use sw_reset")]
368 pub async fn reset_get(&mut self) -> Result<u8, Error<B::Error>> {
369 let val: u8 = CfgRegA::read(self).await?.soft_rst();
370
371 Ok(val)
372 }
373
374 pub async fn reboot(&mut self) -> Result<(), Error<B::Error>> {
375 let mut reg = CfgRegA::read(self).await?;
376 reg.set_reboot(1);
377 reg.write(self).await?;
378
379 self.tim.delay_ms(20).await;
380
381 Ok(())
382 }
383
384 #[deprecated(since = "2.0.0", note = "please use reboot")]
388 pub async fn boot_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
389 let mut reg = CfgRegA::read(self).await?;
390 reg.set_reboot(val);
391 reg.write(self).await?;
392
393 Ok(())
394 }
395 #[deprecated(since = "2.0.0", note = "please use reboot")]
397 pub async fn boot_get(&mut self) -> Result<u8, Error<B::Error>> {
398 let val: u8 = CfgRegA::read(self).await?.reboot();
399
400 Ok(val)
401 }
402 pub async fn self_test_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
404 let mut reg = CfgRegC::read(self).await?;
405 reg.set_self_test(val);
406 reg.write(self).await?;
407
408 Ok(())
409 }
410 pub async fn self_test_get(&mut self) -> Result<u8, Error<B::Error>> {
412 let val: u8 = CfgRegC::read(self).await?.self_test();
413
414 Ok(val)
415 }
416 pub async fn data_format_set(&mut self, val: Ble) -> Result<(), Error<B::Error>> {
418 let mut reg = CfgRegC::read(self).await?;
419 reg.set_ble(val as u8);
420 reg.write(self).await?;
421
422 Ok(())
423 }
424 pub async fn data_format_get(&mut self) -> Result<Ble, Error<B::Error>> {
426 let reg = CfgRegC::read(self).await?;
427
428 let val = Ble::try_from(reg.ble()).unwrap_or_default();
429 Ok(val)
430 }
431 pub async fn status_get(&mut self) -> Result<StatusReg, Error<B::Error>> {
433 let val = StatusReg::read(self).await?;
434
435 Ok(val)
436 }
437 pub async fn offset_int_conf_set(&mut self, val: IntOnDataoff) -> Result<(), Error<B::Error>> {
440 let mut reg = CfgRegB::read(self).await?;
441 reg.set_int_on_dataoff(val as u8);
442 reg.write(self).await?;
443
444 Ok(())
445 }
446 pub async fn offset_int_conf_get(&mut self) -> Result<IntOnDataoff, Error<B::Error>> {
449 let reg = CfgRegB::read(self).await?;
450
451 let val = IntOnDataoff::try_from(reg.int_on_dataoff()).unwrap_or_default();
452 Ok(val)
453 }
454 pub async fn drdy_on_pin_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
456 let mut reg = CfgRegC::read(self).await?;
457 reg.set_drdy_on_pin(val);
458 reg.write(self).await?;
459
460 Ok(())
461 }
462 pub async fn drdy_on_pin_get(&mut self) -> Result<u8, Error<B::Error>> {
464 let val: u8 = CfgRegC::read(self).await?.drdy_on_pin();
465
466 Ok(val)
467 }
468 pub async fn int_on_pin_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
470 let mut reg = CfgRegC::read(self).await?;
471 reg.set_int_on_pin(val);
472 reg.write(self).await?;
473
474 Ok(())
475 }
476 pub async fn int_on_pin_get(&mut self) -> Result<u8, Error<B::Error>> {
478 let val: u8 = CfgRegC::read(self).await?.int_on_pin();
479
480 Ok(val)
481 }
482 pub async fn int_gen_conf_set(&mut self, val: &IntCrtlReg) -> Result<(), Error<B::Error>> {
484 val.write(self).await
485 }
486 pub async fn int_gen_conf_get(&mut self) -> Result<IntCrtlReg, Error<B::Error>> {
488 IntCrtlReg::read(self).await
489 }
490 pub async fn int_gen_source_get(&mut self) -> Result<IntSourceReg, Error<B::Error>> {
492 IntSourceReg::read(self).await
493 }
494 pub async fn int_gen_threshold_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
499 IntThs::new().with_threshold(val).write(self).await
500 }
501 pub async fn int_gen_threshold_get(&mut self) -> Result<u16, Error<B::Error>> {
506 Ok(IntThs::read(self).await?.threshold())
507 }
508 pub async fn spi_mode_set(&mut self, val: Sim) -> Result<(), Error<B::Error>> {
512 let mut reg_val = CfgRegC::read(self).await?;
513 reg_val.set_four_wire_spi(val as u8);
514 reg_val.write(self).await?;
515
516 Ok(())
517 }
518
519 pub async fn spi_mode_get(&mut self) -> Result<Sim, Error<B::Error>> {
521 let reg_val = CfgRegC::read(self).await?;
522
523 let val = Sim::try_from(reg_val.four_wire_spi()).unwrap_or_default();
524 Ok(val)
525 }
526
527 pub async fn i2c_interface_set(&mut self, val: I2cSwitch) -> Result<(), Error<B::Error>> {
531 let mut reg = CfgRegC::read(self).await?;
532 reg.set_i2c_dis(val as u8);
533 reg.write(self).await?;
534
535 Ok(())
536 }
537 pub async fn i2c_interface_get(&mut self) -> Result<I2cSwitch, Error<B::Error>> {
539 let reg = CfgRegC::read(self).await?;
540
541 let val = I2cSwitch::try_from(reg.i2c_dis()).unwrap_or_default();
542 Ok(val)
543 }
544}
545
546#[bisync]
547pub fn from_lsb_to_mgauss(lsb: i16) -> f32 {
548 lsb as f32 * 1.5
549}
550
551#[bisync]
552pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
553 lsb as f32 / 8.0 + 25.0
554}
555
556#[repr(u8)]
557#[derive(Clone, Copy, PartialEq)]
558#[bisync]
559pub enum I2CAddress {
560 I2cAdd = 0x1E,
561}
562
563#[bisync]
564pub const ID: u8 = 0x40;