1#![cfg_attr(not(test), no_std)]
2#![allow(dead_code)]
3
4mod consts;
5mod data;
6pub mod interface;
7mod registers;
8mod settings;
9
10use consts::*;
11pub use data::XYZ;
12use interface::Interface;
13pub use registers::{AccelSampleRate, AccelScale};
14use registers::{
15 Ctrl3C, GyroSampleRate, GyroScale, RegisterAddress, RegisterBits, RegisterConfig,
16 RegisterValue, TapSrc, WakeUpSrc,
17};
18pub use settings::{
19 irq::{InterruptRoute, TapIrqSettings, TapRecognitionMode},
20 AccelSettings, GyroSettings, IrqSettings, LsmSettings,
21};
22
23extern crate alloc;
24use alloc::vec::Vec;
25
26pub struct LSM6DS3TR<I>
28where
29 I: Interface,
30{
31 interface: I,
32 pub settings: LsmSettings,
33}
34
35impl<I> LSM6DS3TR<I>
36where
37 I: Interface,
38{
39 pub fn new(interface: I) -> Self {
41 Self {
42 interface,
43 settings: Default::default(),
44 }
45 }
46
47 pub fn with_settings(mut self, settings: LsmSettings) -> Self {
49 self.settings = settings;
50 self
51 }
52
53 pub fn init(&mut self) -> Result<(), I::Error> {
55 self.init_accel()?;
56 self.init_gyro()?;
57 self.init_irqs()?;
58 self.init_other()?;
59 Ok(())
60 }
61
62 pub fn is_reachable(&mut self) -> Result<bool, I::Error> {
64 Ok(self.read_register(RegisterAddress::WHO_AM_I.address())? == LSM6DS3TR_ID)
65 }
66
67 pub fn software_reset(&mut self) -> Result<(), I::Error> {
69 let ctrl3_c = Ctrl3C {
70 software_reset: RegisterBits::new(1),
71 ..Default::default()
72 };
73 self.write_register_config(ctrl3_c.config())?;
74 Ok(())
75 }
76
77 pub fn init_accel(&mut self) -> Result<(), I::Error> {
79 self.write_register_config(self.settings.accel.config())?;
80 Ok(())
81 }
82
83 pub fn init_gyro(&mut self) -> Result<(), I::Error> {
85 self.write_register_config(self.settings.gyro.config())?;
86 Ok(())
87 }
88
89 pub fn init_irqs(&mut self) -> Result<(), I::Error> {
91 for config in self.settings.irq.configs() {
92 self.write_register_config(config)?;
93 }
94 Ok(())
95 }
96
97 pub fn init_other(&mut self) -> Result<(), I::Error> {
99 if self.settings.low_performance_mode {
100 self.write_register(RegisterAddress::CTRL6_C.address(), 1 << 4)?; self.write_register(RegisterAddress::CTRL7_G.address(), 1 << 7)?; }
103 Ok(())
104 }
105
106 pub fn read_accel_raw(&mut self) -> Result<XYZ<i16>, I::Error> {
108 self.read_sensor_raw(RegisterAddress::OUTX_L_XL.address())
109 }
110
111 pub fn read_accel(&mut self) -> Result<XYZ<f32>, I::Error> {
113 let xyz = self.read_accel_raw()?;
114 let sensitivity = self.settings.accel.scale.sensitivity();
115 Ok(XYZ {
116 x: xyz.x as f32 * sensitivity,
117 y: xyz.y as f32 * sensitivity,
118 z: xyz.z as f32 * sensitivity,
119 })
120 }
121
122 pub fn read_gyro_raw(&mut self) -> Result<XYZ<i16>, I::Error> {
124 self.read_sensor_raw(RegisterAddress::OUTX_L_G.address())
125 }
126
127 pub fn read_gyro(&mut self) -> Result<XYZ<f32>, I::Error> {
129 let xyz = self.read_gyro_raw()?;
130 let sensitivity = self.settings.gyro.scale.sensitivity();
131 Ok(XYZ {
132 x: xyz.x as f32 * sensitivity,
133 y: xyz.y as f32 * sensitivity,
134 z: xyz.z as f32 * sensitivity,
135 })
136 }
137
138 pub fn read_temp_raw(&mut self) -> Result<i16, I::Error> {
140 let mut bytes = [0u8; 2];
141 self.interface
142 .read(RegisterAddress::OUT_TEMP_L.address(), &mut bytes)?;
143 let temp: i16 = (bytes[1] as i16) << 8 | bytes[0] as i16;
144 Ok(temp)
145 }
146
147 pub fn read_temp(&mut self) -> Result<f32, I::Error> {
149 let temp = self.read_temp_raw()?;
150 Ok(temp as f32 / TEMP_SCALE + TEMP_BIAS)
151 }
152
153 pub fn read_interrupt_sources(&mut self) -> Result<Vec<IrqSource>, I::Error> {
155 let mut wake_up_src = WakeUpSrc::default();
156 let mut tap_src = TapSrc::default();
157 wake_up_src = self.read_register(wake_up_src.address())?.into();
160 tap_src = self.read_register(tap_src.address())?.into();
161 let mut irq_sources = Vec::new();
162 for source in wake_up_src.get_irq_sources() {
163 irq_sources.push(source.clone());
164 }
165 for source in tap_src.get_irq_sources() {
166 irq_sources.push(source.clone());
167 }
168 Ok(irq_sources)
169 }
170
171 fn read_sensor_raw(&mut self, addr: u8) -> Result<XYZ<i16>, I::Error> {
172 let mut bytes = [0u8; 6];
173 self.interface.read(addr, &mut bytes)?;
174 let x: i16 = (bytes[1] as i16) << 8 | bytes[0] as i16;
175 let y: i16 = (bytes[3] as i16) << 8 | bytes[2] as i16;
176 let z: i16 = (bytes[5] as i16) << 8 | bytes[4] as i16;
177 Ok(XYZ { x, y, z })
178 }
179
180 fn read_register(&mut self, address: u8) -> Result<u8, I::Error> {
181 let mut value = [0u8];
182 self.interface.read(address, &mut value)?;
183 Ok(value[0])
184 }
185
186 fn write_register(&mut self, address: u8, value: u8) -> Result<(), I::Error> {
187 self.interface.write(address, value)?;
188 Ok(())
189 }
190
191 fn read_register_config(&mut self, address: u8) -> Result<RegisterConfig, I::Error> {
192 let mut value = [0u8];
193 self.interface.read(address, &mut value)?;
194 let value = value[0];
195 Ok(RegisterConfig { address, value })
196 }
197
198 fn write_register_config(&mut self, register_config: RegisterConfig) -> Result<(), I::Error> {
199 self.write_register(register_config.address, register_config.value)?;
200 Ok(())
201 }
202}
203
204#[cfg_attr(feature = "defmt", derive(defmt::Format))]
206#[derive(Clone, Debug)]
207pub enum IrqSource {
208 FreeFall,
209 Sleep,
210 WakeUp,
211 WakeUpOnX,
212 WakeUpOnY,
213 WakeUpOnZ,
214 Tap,
215 SingleTap,
216 DoubleTap,
217 TapOnX,
218 TapOnY,
219 TapOnZ,
220}
221
222pub struct IrqSources(pub Vec<IrqSource>);