1#![cfg_attr(not(feature = "std"), no_std)]
16#![doc = include_str!("../README.md")]
17
18pub mod config;
19pub mod interrupt;
20pub mod modes;
21pub mod register;
22pub mod status;
23
24pub use config::*;
25pub use interrupt::*;
26pub use modes::*;
27pub use register::*;
28pub use status::*;
29
30use embedded_hal::i2c::I2c;
31use embedded_hal::spi;
32use embedded_hal::spi::SpiDevice;
33use micromath::vector::{F32x3, I32x3};
34
35pub const DEVICE_ID: u8 = 0xED;
37
38#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
39#[cfg_attr(feature = "defmt", derive(defmt::Format))]
40#[repr(u8)]
41pub enum DeviceI2cAddress {
43 #[default]
44 AselPinLow = 0x1D,
46 AselPinHigh = 0x53,
48}
49
50pub struct Adxl355<PROTOCOL: Protocol> {
52 pub protocol: PROTOCOL,
53 shadow_values: [u8; 5],
54 range_scale_factor: f32,
55}
56
57impl<SPI> Adxl355<SpiProtocol<SPI>>
58where
59 SPI: SpiDevice,
60{
61 pub fn new_spi(spi: SPI) -> Result<Self, Error<SPI::Error>> {
63 let mut adxl355 = Adxl355 {
64 protocol: SpiProtocol { spi },
65 shadow_values: [0; 5],
66 range_scale_factor: 0.0,
67 };
68 let dev_id = adxl355.get_device_id()?;
69 if dev_id != DEVICE_ID {
70 return Err(Error::BadDeviceId(dev_id));
71 }
72 adxl355.init_shadow_values()?;
73 adxl355.range_scale_factor = adxl355.get_range()?.scale_factor();
74 Ok(adxl355)
75 }
76
77 pub fn new_spi_with_config(spi: SPI, config: Config) -> Result<Self, Error<SPI::Error>> {
80 let mut adxl355 = Self::new_spi(spi)?;
81 adxl355.configure(config)?;
82 Ok(adxl355)
83 }
84}
85
86impl<I2C> Adxl355<I2cProtocol<I2C>>
87where
88 I2C: I2c,
89{
90 pub fn new_i2c(i2c: I2C, address: DeviceI2cAddress) -> Result<Self, Error<I2C::Error>> {
92 let mut adxl355 = Adxl355 {
93 protocol: I2cProtocol {
94 i2c,
95 address: address as u8,
96 },
97 shadow_values: [0; 5],
98 range_scale_factor: 0.0,
99 };
100 let dev_id = adxl355.get_device_id()?;
101 if dev_id != DEVICE_ID {
102 return Err(Error::BadDeviceId(dev_id));
103 }
104 adxl355.init_shadow_values()?;
105 adxl355.range_scale_factor = adxl355.get_range()?.scale_factor();
106 Ok(adxl355)
107 }
108
109 pub fn new_i2c_with_config(
112 i2c: I2C,
113 address: DeviceI2cAddress,
114 config: Config,
115 ) -> Result<Self, Error<I2C::Error>> {
116 let mut adxl355 = Self::new_i2c(i2c, address)?;
117 adxl355.configure(config)?;
118 Ok(adxl355)
119 }
120}
121
122impl<PROTOCOL> Adxl355<PROTOCOL>
123where
124 PROTOCOL: Protocol,
125{
126 pub fn configure(&mut self, config: Config) -> Result<(), Error<PROTOCOL::ProtocolError>> {
129 self.reset()?;
130
131 let mode = self.get_mode()?;
132
133 if !mode.is_in_standby() {
134 return Err(Error::DeviceRunning);
135 }
136
137 self.protocol
138 .write_register(Register::FILTER, (config.hpf.val() << 4) | config.odr.val())?;
139 let mut range_register_value = self.protocol.read_register(Register::RANGE)?;
140 range_register_value |= config.range.val();
141 self.protocol
142 .write_register(Register::RANGE, range_register_value)?;
143 self.range_scale_factor = config.range.scale_factor();
144
145 Ok(())
146 }
147
148 pub fn get_status(&mut self) -> Result<Status, Error<PROTOCOL::ProtocolError>> {
150 let status_val = self.protocol.read_register(Register::STATUS)?;
151 Ok(Status(status_val))
152 }
153
154 pub fn get_device_id(&mut self) -> Result<u8, Error<PROTOCOL::ProtocolError>> {
156 self.protocol.read_register(Register::PARTID)
157 }
158
159 pub fn get_revision_id(&mut self) -> Result<u8, Error<PROTOCOL::ProtocolError>> {
161 self.protocol.read_register(Register::REVID)
162 }
163
164 pub fn reset(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
166 self.protocol.write_register(Register::RESET, 0x52)?;
167
168 let mut nb_of_retries = 255;
169 let mut nvm_busy = self.get_status()?.is_nvm_busy();
170
171 while nvm_busy && nb_of_retries > 0 {
172 nvm_busy = self.get_status()?.is_nvm_busy();
173 nb_of_retries -= 1;
174 }
175
176 if nb_of_retries == 0 || nvm_busy {
177 return Err(Error::SoftResetFailed);
178 }
179
180 let shadow_values = self.get_shadow_values()?;
181
182 if self.shadow_values == shadow_values {
183 Ok(())
184 } else {
185 Err(Error::SoftResetFailed)
186 }
187 }
188
189 pub fn get_mode(&mut self) -> Result<Mode, Error<PROTOCOL::ProtocolError>> {
191 self.protocol.read_register(Register::POWER_CTL).map(Mode)
192 }
193
194 pub fn set_mode(&mut self, mode: Mode) -> Result<(), Error<PROTOCOL::ProtocolError>> {
196 self.protocol.write_register(Register::POWER_CTL, mode.0)
197 }
198
199 pub fn get_range(&mut self) -> Result<Range, Error<PROTOCOL::ProtocolError>> {
201 self.protocol
202 .read_register(Register::RANGE)
203 .map(Range::from)
204 }
205
206 pub fn get_odr_lpf(&mut self) -> Result<Odr, Error<PROTOCOL::ProtocolError>> {
208 self.protocol.read_register(Register::FILTER).map(Odr::from)
209 }
210
211 pub fn get_hpf_corner(&mut self) -> Result<HpfCorner, Error<PROTOCOL::ProtocolError>> {
213 self.protocol
214 .read_register(Register::FILTER)
215 .map(HpfCorner::from)
216 }
217
218 pub fn get_config(&mut self) -> Result<Config, Error<PROTOCOL::ProtocolError>> {
220 let range = self.get_range()?;
221
222 let filter_val = self.protocol.read_register(Register::FILTER)?;
223 let odr = Odr::from(filter_val);
224 let hpf = HpfCorner::from(filter_val);
225
226 Ok(Config { range, odr, hpf })
227 }
228
229 pub fn set_measurement_mode(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
231 let mode = self.protocol.read_register(Register::POWER_CTL)?;
232 self.protocol
233 .write_register(Register::POWER_CTL, mode & !Mode::STANDBY_BIT)
234 }
235
236 pub fn set_standby_mode(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
238 let mode = self.protocol.read_register(Register::POWER_CTL)?;
239 self.protocol
240 .write_register(Register::POWER_CTL, mode | Mode::STANDBY_BIT)
241 }
242
243 pub fn get_temperature_raw(&mut self) -> Result<u16, Error<PROTOCOL::ProtocolError>> {
245 let mut buf: [u8; 2] = [0; 2];
246
247 self.protocol
248 .read_multiple_registers(Register::TEMP2, &mut buf)?;
249
250 Ok((((buf[0] & 0x0F) as u16) << 8) | ((buf[1] as u16) & 0xFF))
251 }
252
253 pub fn get_temparature(&mut self) -> Result<f32, Error<PROTOCOL::ProtocolError>> {
255 let raw_temp = self.get_temperature_raw()?;
256 Ok(((((raw_temp as i32) - 1885i32) as f32) / (-9.05f32)) + 25.0f32)
257 }
258
259 pub fn get_raw_accel_sample(&mut self) -> Result<I32x3, Error<PROTOCOL::ProtocolError>> {
261 let mut buf: [u8; 9] = [0; 9];
262 self.protocol
263 .read_multiple_registers(Register::XDATA3, &mut buf)?;
264
265 let mut sample = I32x3 { x: 0, y: 0, z: 0 };
266
267 Self::acc_buf_to_raw_sample(&buf, &mut sample);
268
269 Ok(sample)
270 }
271
272 pub fn get_accel_sample(&mut self) -> Result<F32x3, Error<PROTOCOL::ProtocolError>> {
274 let mut buf: [u8; 9] = [0; 9];
275 self.protocol
276 .read_multiple_registers(Register::XDATA3, &mut buf)?;
277
278 let mut sample = F32x3 {
279 x: 0.0,
280 y: 0.0,
281 z: 0.0,
282 };
283
284 Self::acc_buf_to_sample(&buf, &mut sample, self.range_scale_factor);
285
286 Ok(sample)
287 }
288
289 pub fn start_self_test(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
291 self.protocol.write_register(Register::SELF_TEST, 0x03)
292 }
293
294 pub fn stop_self_test(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
296 self.protocol.write_register(Register::SELF_TEST, 0x00)
297 }
298
299 pub fn set_offset_trims(
302 &mut self,
303 offset_x: i16,
304 offset_y: i16,
305 offset_z: i16,
306 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
307 let mut buf = [
308 Register::OFFSET_X_H.addr(),
309 ((offset_x >> 8) & 0xFF) as u8,
310 ((offset_x) & 0xFF) as u8,
311 ((offset_y >> 8) & 0xFF) as u8,
312 ((offset_y) & 0xFF) as u8,
313 ((offset_z >> 8) & 0xFF) as u8,
314 ((offset_z) & 0xFF) as u8,
315 ];
316 self.protocol.write_multiple_registers(&mut buf)
317 }
318
319 pub fn get_nb_samples_in_fifo(&mut self) -> Result<u8, Error<PROTOCOL::ProtocolError>> {
321 let nb_samples = self.protocol.read_register(Register::FIFO_ENTRIES)? & 0x7F;
322 Ok(nb_samples)
323 }
324
325 pub fn set_nb_max_samples_in_fifo(
328 &mut self,
329 fifo_samples: u8,
330 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
331 if !(1..=96).contains(&fifo_samples) {
332 return Err(Error::InvalidMaxNbFifoSamples);
333 }
334
335 self.protocol
336 .write_register(Register::FIFO_SAMPLES, fifo_samples)
337 }
338
339 pub fn get_fifo_raw_data(
342 &mut self,
343 data: &mut [I32x3],
344 ) -> Result<usize, Error<PROTOCOL::ProtocolError>> {
345 let mut nb_available_samples = self.get_nb_samples_in_fifo()?;
346 if nb_available_samples < 3 {
347 return Err(Error::NotEnoughData);
348 }
349 let data_len = data.len();
350 let mut nb_samples_retrieved: usize = 0;
351
352 let mut buf = [0u8; 9];
353 self.protocol
354 .read_multiple_registers(Register::FIFO_DATA, &mut buf[..3])?;
355 nb_available_samples -= 1;
356
357 while buf[2] & 0x01 == 0 {
359 if nb_available_samples < 3 {
360 return Err(Error::NotEnoughData);
361 }
362
363 self.protocol
364 .read_multiple_registers(Register::FIFO_DATA, &mut buf[..3])?;
365 nb_available_samples -= 1;
366 }
367
368 self.protocol
369 .read_multiple_registers(Register::FIFO_DATA, &mut buf[3..])?;
370 nb_available_samples -= 2;
371
372 Self::acc_buf_to_raw_sample(&buf, &mut data[0]);
373 nb_samples_retrieved += 1;
374
375 while nb_available_samples >= 3 && data_len > nb_samples_retrieved {
376 self.protocol
377 .read_multiple_registers(Register::FIFO_DATA, &mut buf)?;
378 nb_available_samples -= 3;
379
380 Self::acc_buf_to_raw_sample(&buf, &mut data[nb_samples_retrieved]);
381 nb_samples_retrieved += 1;
382 }
383
384 Ok(nb_samples_retrieved)
385 }
386
387 pub fn get_fifo_data(
390 &mut self,
391 data: &mut [F32x3],
392 ) -> Result<usize, Error<PROTOCOL::ProtocolError>> {
393 let mut nb_available_samples = self.get_nb_samples_in_fifo()?;
394 if nb_available_samples < 3 {
395 return Err(Error::NotEnoughData);
396 }
397 let data_len = data.len();
398 let mut nb_samples_retrieved: usize = 0;
399
400 let mut buf = [0u8; 9];
401 self.protocol
402 .read_multiple_registers(Register::FIFO_DATA, &mut buf[..3])?;
403 nb_available_samples -= 1;
404
405 while buf[2] & 0x01 == 0 {
407 if nb_available_samples < 3 {
408 return Err(Error::NotEnoughData);
409 }
410
411 self.protocol
412 .read_multiple_registers(Register::FIFO_DATA, &mut buf[..3])?;
413 nb_available_samples -= 1;
414 }
415
416 self.protocol
417 .read_multiple_registers(Register::FIFO_DATA, &mut buf[3..])?;
418 nb_available_samples -= 2;
419
420 Self::acc_buf_to_sample(&buf, &mut data[0], self.range_scale_factor);
421 nb_samples_retrieved += 1;
422
423 while nb_available_samples >= 3 && data_len > nb_samples_retrieved {
424 self.protocol
425 .read_multiple_registers(Register::FIFO_DATA, &mut buf)?;
426 nb_available_samples -= 3;
427
428 Self::acc_buf_to_sample(
429 &buf,
430 &mut data[nb_samples_retrieved],
431 self.range_scale_factor,
432 );
433 nb_samples_retrieved += 1;
434 }
435
436 Ok(nb_samples_retrieved)
437 }
438
439 pub fn enable_activity_detection(
441 &mut self,
442 x: bool,
443 y: bool,
444 z: bool,
445 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
446 let mut act_en = 0;
447 if x {
448 act_en += 0x01;
449 }
450 if y {
451 act_en += 0x02;
452 }
453 if z {
454 act_en += 0x04;
455 }
456
457 self.protocol.write_register(Register::ACT_EN, act_en)
458 }
459
460 pub fn set_activity_threshold(
465 &mut self,
466 threshold: u16,
467 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
468 self.protocol.write_multiple_registers(&mut [
469 Register::ACT_THRESH_H.addr(),
470 ((threshold >> 8) & 0xFF) as u8,
471 (threshold & 0xFF) as u8,
472 ])
473 }
474
475 pub fn set_activity_count(&mut self, count: u8) -> Result<(), Error<PROTOCOL::ProtocolError>> {
477 self.protocol.write_register(Register::ACT_COUNT, count)
478 }
479
480 pub fn configure_interrupt_pins(
482 &mut self,
483 conf: InterruptConfig,
484 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
485 self.protocol.write_register(Register::INT_MAP, conf.0)
486 }
487
488 pub fn set_interrupt_polarity(
490 &mut self,
491 polarity: InterruptPolarity,
492 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
493 let mut buf = self.protocol.read_register(Register::RANGE)?;
494
495 match polarity {
496 InterruptPolarity::ActiveHigh => {
497 buf |= 0x40;
498 }
499 InterruptPolarity::ActiveLow => {
500 buf &= !0x40;
501 }
502 }
503
504 self.protocol.write_register(Register::RANGE, buf)
505 }
506
507 pub fn set_i2c_speed(
509 &mut self,
510 mode: I2cSpeedMode,
511 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
512 let mut buf = self.protocol.read_register(Register::RANGE)?;
513
514 match mode {
515 I2cSpeedMode::HighSpeed => {
516 buf |= 0x80;
517 }
518 I2cSpeedMode::Fast => {
519 buf &= !0x80;
520 }
521 }
522
523 self.protocol.write_register(Register::RANGE, buf)
524 }
525
526 pub fn set_synchronization_mode(
528 &mut self,
529 mode: ExternalSyncMode,
530 ) -> Result<(), Error<PROTOCOL::ProtocolError>> {
531 self.protocol.write_register(Register::SYNC, mode as u8)
532 }
533
534 fn acc_buf_to_raw_sample(buf: &[u8; 9], sample: &mut I32x3) {
536 sample.x =
537 (((buf[0] as i32) << 24) | ((buf[1] as i32) << 16) | ((buf[2] & 0xF0) as i32) << 8)
538 >> 12;
539 sample.y =
540 (((buf[3] as i32) << 24) | ((buf[4] as i32) << 16) | ((buf[5] & 0xF0) as i32) << 8)
541 >> 12;
542 sample.z =
543 (((buf[6] as i32) << 24) | ((buf[7] as i32) << 16) | ((buf[8] & 0xF0) as i32) << 8)
544 >> 12;
545 }
546
547 fn acc_buf_to_sample(buf: &[u8; 9], sample: &mut F32x3, scale_factor: f32) {
549 sample.x =
550 ((((buf[0] as i32) << 24) | ((buf[1] as i32) << 16) | ((buf[2] & 0xF0) as i32) << 8)
551 >> 12) as f32
552 * scale_factor;
553 sample.y =
554 ((((buf[3] as i32) << 24) | ((buf[4] as i32) << 16) | ((buf[5] & 0xF0) as i32) << 8)
555 >> 12) as f32
556 * scale_factor;
557 sample.z =
558 ((((buf[6] as i32) << 24) | ((buf[7] as i32) << 16) | ((buf[8] & 0xF0) as i32) << 8)
559 >> 12) as f32
560 * scale_factor;
561 }
562
563 fn init_shadow_values(&mut self) -> Result<(), Error<PROTOCOL::ProtocolError>> {
565 self.protocol
566 .read_multiple_registers(Register::SHADOW_REG1, &mut self.shadow_values)?;
567 Ok(())
568 }
569
570 fn get_shadow_values(&mut self) -> Result<[u8; 5], Error<PROTOCOL::ProtocolError>> {
572 let mut shadow_values = [0u8; 5];
573 self.protocol
574 .read_multiple_registers(Register::SHADOW_REG1, &mut shadow_values)?;
575 Ok(shadow_values)
576 }
577}
578
579pub trait Protocol {
580 type ProtocolError: core::fmt::Debug;
581
582 fn read_register(&mut self, register: Register) -> Result<u8, Error<Self::ProtocolError>>;
584
585 fn read_multiple_registers(
587 &mut self,
588 start_register: Register,
589 buf: &mut [u8],
590 ) -> Result<(), Error<Self::ProtocolError>>;
591
592 fn write_register(
594 &mut self,
595 register: Register,
596 buf: u8,
597 ) -> Result<(), Error<Self::ProtocolError>>;
598
599 fn write_multiple_registers(
601 &mut self,
602 buf: &mut [u8],
603 ) -> Result<(), Error<Self::ProtocolError>>;
604}
605
606pub struct SpiProtocol<SPI> {
607 spi: SPI,
608}
609
610impl<SPI> Protocol for SpiProtocol<SPI>
611where
612 SPI: SpiDevice,
613{
614 type ProtocolError = SPI::Error;
615
616 fn read_register(&mut self, register: Register) -> Result<u8, Error<Self::ProtocolError>> {
618 let mut buf = [0u8; 1];
619 self.spi
620 .transaction(&mut [
621 spi::Operation::Write(&[register.addr() << 1 | 0x01]),
622 spi::Operation::Read(&mut buf),
623 ])
624 .map_err(Error::Protocol)?;
625 Ok(buf[0])
626 }
627
628 fn read_multiple_registers(
630 &mut self,
631 start_register: Register,
632 buf: &mut [u8],
633 ) -> Result<(), Error<Self::ProtocolError>> {
634 self.spi
635 .transaction(&mut [
636 spi::Operation::Write(&[(start_register.addr() << 1) | 0x01]),
637 spi::Operation::Read(buf),
638 ])
639 .map_err(Error::Protocol)?;
640 Ok(())
641 }
642
643 fn write_register(
645 &mut self,
646 register: Register,
647 buf: u8,
648 ) -> Result<(), Error<Self::ProtocolError>> {
649 self.spi
650 .write(&[register.addr() << 1, buf])
651 .map_err(Error::Protocol)?;
652 Ok(())
653 }
654
655 fn write_multiple_registers(
657 &mut self,
658 buf: &mut [u8],
659 ) -> Result<(), Error<Self::ProtocolError>> {
660 buf[0] <<= 1;
661 self.spi.write(buf).map_err(Error::Protocol)?;
662 Ok(())
663 }
664}
665
666pub struct I2cProtocol<I2C> {
667 i2c: I2C,
668 address: u8,
669}
670
671impl<I2C> Protocol for I2cProtocol<I2C>
672where
673 I2C: I2c,
674{
675 type ProtocolError = I2C::Error;
676
677 fn read_register(&mut self, register: Register) -> Result<u8, Error<Self::ProtocolError>> {
679 let mut buf = [0u8; 1];
680 self.i2c
681 .write_read(self.address, &[register.addr()], &mut buf)
682 .map_err(Error::Protocol)?;
683 Ok(buf[0])
684 }
685
686 fn read_multiple_registers(
688 &mut self,
689 start_register: Register,
690 buf: &mut [u8],
691 ) -> Result<(), Error<Self::ProtocolError>> {
692 self.i2c
693 .write_read(self.address, &[start_register.addr()], buf)
694 .map_err(Error::Protocol)?;
695 Ok(())
696 }
697
698 fn write_register(
700 &mut self,
701 register: Register,
702 buf: u8,
703 ) -> Result<(), Error<Self::ProtocolError>> {
704 self.i2c
705 .write(self.address, &[register.addr(), buf])
706 .map_err(Error::Protocol)?;
707 Ok(())
708 }
709
710 fn write_multiple_registers(
712 &mut self,
713 buf: &mut [u8],
714 ) -> Result<(), Error<Self::ProtocolError>> {
715 self.i2c.write(self.address, buf).map_err(Error::Protocol)?;
716 Ok(())
717 }
718}
719
720#[derive(Copy, Clone, Debug)]
721#[cfg_attr(feature = "defmt", derive(defmt::Format))]
722#[cfg_attr(feature = "std", derive(thiserror::Error))]
723pub enum Error<ProtocolError: core::fmt::Debug> {
725 #[cfg_attr(feature = "std", error("protocol error: {0:?}"))]
727 Protocol(ProtocolError),
728
729 #[cfg_attr(feature = "std", error("unexpected device ID: {0}"))]
731 BadDeviceId(u8),
732
733 #[cfg_attr(
735 feature = "std",
736 error("device is in measure mode and cannot be configured")
737 )]
738 DeviceRunning,
739
740 #[cfg_attr(feature = "std", error("device software reset failed"))]
742 SoftResetFailed,
743
744 #[cfg_attr(
746 feature = "std",
747 error("max number of fifo samples must range from 1 to 96")
748 )]
749 InvalidMaxNbFifoSamples,
750
751 #[cfg_attr(feature = "std", error("not enough data in the fifo"))]
753 NotEnoughData,
754}