1#![no_std]
48
49mod bits;
50pub mod device;
51
52use crate::device::*;
53use libm::{powf, atan2f, sqrtf};
54use nalgebra::{Vector3, Vector2};
55use embedded_hal::{
56 blocking::delay::DelayMs,
57 blocking::i2c::{Write, WriteRead},
58};
59pub const PI: f32 = core::f32::consts::PI;
62
63pub const PI_180: f32 = PI / 180.0;
65
66#[derive(Debug)]
68pub enum Mpu6886Error<E> {
69 I2c(E),
71
72 InvalidChipId(u8),
74}
75
76pub struct Mpu6886<I> {
78 i2c: I,
79 slave_addr: u8,
80 acc_sensitivity: f32,
81 gyro_sensitivity: f32,
82}
83
84impl<I, E> Mpu6886<I>
85where
86 I: Write<Error = E> + WriteRead<Error = E>,
87{
88 pub fn new(i2c: I) -> Self {
90 Mpu6886 {
91 i2c,
92 slave_addr: DEFAULT_SLAVE_ADDR,
93 acc_sensitivity: ACCEL_SENS.0,
94 gyro_sensitivity: GYRO_SENS.0,
95 }
96 }
97
98 pub fn new_with_sens(i2c: I, arange: AccelRange, grange: GyroRange) -> Self {
100 Mpu6886 {
101 i2c,
102 slave_addr: DEFAULT_SLAVE_ADDR,
103 acc_sensitivity: arange.sensitivity(),
104 gyro_sensitivity: grange.sensitivity(),
105 }
106 }
107
108 pub fn new_with_addr(i2c: I, slave_addr: u8) -> Self {
110 Mpu6886 {
111 i2c,
112 slave_addr,
113 acc_sensitivity: ACCEL_SENS.0,
114 gyro_sensitivity: GYRO_SENS.0,
115 }
116 }
117
118 pub fn new_with_addr_and_sens(i2c: I, slave_addr: u8, arange: AccelRange, grange: GyroRange) -> Self {
120 Mpu6886 {
121 i2c,
122 slave_addr,
123 acc_sensitivity: arange.sensitivity(),
124 gyro_sensitivity: grange.sensitivity(),
125 }
126 }
127
128 fn wake<D: DelayMs<u8>>(&mut self, delay: &mut D) -> Result<(), Mpu6886Error<E>> {
130 self.write_byte(PWR_MGMT_1::ADDR, 0x01)?;
133 delay.delay_ms(100u8);
134 Ok(())
135 }
136
137 pub fn set_clock_source(&mut self, source: CLKSEL) -> Result<(), Mpu6886Error<E>> {
147 Ok(self.write_bits(PWR_MGMT_1::ADDR, PWR_MGMT_1::CLKSEL.bit, PWR_MGMT_1::CLKSEL.length, source as u8)?)
148 }
149
150 pub fn get_clock_source(&mut self) -> Result<CLKSEL, Mpu6886Error<E>> {
152 let source = self.read_bits(PWR_MGMT_1::ADDR, PWR_MGMT_1::CLKSEL.bit, PWR_MGMT_1::CLKSEL.length)?;
153 Ok(CLKSEL::from(source))
154 }
155
156 pub fn init<D: DelayMs<u8>>(&mut self, delay: &mut D) -> Result<(), Mpu6886Error<E>> {
158 self.wake(delay)?;
159 self.verify()?;
160 self.set_accel_range(AccelRange::G2)?;
161 self.set_gyro_range(GyroRange::D250)?;
162 Ok(())
163 }
164
165 fn verify(&mut self) -> Result<(), Mpu6886Error<E>> {
167 let chip_type = self.read_byte(WHOAMI)?;
168 if chip_type != 0x19 {
169 return Err(Mpu6886Error::InvalidChipId(chip_type));
170 }
171 Ok(())
172 }
173
174 pub fn setup_motion_detection(&mut self) -> Result<(), Mpu6886Error<E>> {
179 self.write_byte(0x6B, 0x00)?;
180 self.write_byte(INT_PIN_CFG::ADDR, 0x20)?; self.write_byte(ACCEL_CONFIG::ADDR, 0x01)?; self.write_byte(MOT_THR, 10)?; self.write_byte(MOT_DUR, 40)?; self.write_byte(0x69, 0x15)?; self.write_byte(INT_ENABLE::ADDR, 0x40)?; Ok(())
188 }
189
190 pub fn get_motion_detected(&mut self) -> Result<bool, Mpu6886Error<E>> {
192 let mask = INT_STATUS::WOM_X_INT | INT_STATUS::WOM_Y_INT | INT_STATUS::WOM_Z_INT;
193 Ok(self.read_bit(INT_STATUS::ADDR, mask)? != 0)
194 }
195
196
197 pub fn set_gyro_range(&mut self, range: GyroRange) -> Result<(), Mpu6886Error<E>> {
199 self.write_bits(GYRO_CONFIG::ADDR,
200 GYRO_CONFIG::FS_SEL.bit,
201 GYRO_CONFIG::FS_SEL.length,
202 range as u8)?;
203
204 self.gyro_sensitivity = range.sensitivity();
205 Ok(())
206 }
207
208 pub fn get_gyro_range(&mut self) -> Result<GyroRange, Mpu6886Error<E>> {
210 let byte = self.read_bits(GYRO_CONFIG::ADDR,
211 GYRO_CONFIG::FS_SEL.bit,
212 GYRO_CONFIG::FS_SEL.length)?;
213
214 Ok(GyroRange::from(byte))
215 }
216
217 pub fn set_accel_range(&mut self, range: AccelRange) -> Result<(), Mpu6886Error<E>> {
219 self.write_bits(ACCEL_CONFIG::ADDR,
220 ACCEL_CONFIG::FS_SEL.bit,
221 ACCEL_CONFIG::FS_SEL.length,
222 range as u8)?;
223
224 self.acc_sensitivity = range.sensitivity();
225 Ok(())
226 }
227
228 pub fn get_accel_range(&mut self) -> Result<AccelRange, Mpu6886Error<E>> {
230 let byte = self.read_bits(ACCEL_CONFIG::ADDR,
231 ACCEL_CONFIG::FS_SEL.bit,
232 ACCEL_CONFIG::FS_SEL.length)?;
233
234 Ok(AccelRange::from(byte))
235 }
236
237 pub fn reset_device<D: DelayMs<u8>>(&mut self, delay: &mut D) -> Result<(), Mpu6886Error<E>> {
239 self.write_bit(PWR_MGMT_1::ADDR, PWR_MGMT_1::DEVICE_RESET, true)?;
240 delay.delay_ms(100u8);
241 Ok(())
243 }
244
245 pub fn set_sleep_enabled(&mut self, enable: bool) -> Result<(), Mpu6886Error<E>> {
247 Ok(self.write_bit(PWR_MGMT_1::ADDR, PWR_MGMT_1::SLEEP, enable)?)
248 }
249
250 pub fn get_sleep_enabled(&mut self) -> Result<bool, Mpu6886Error<E>> {
252 Ok(self.read_bit(PWR_MGMT_1::ADDR, PWR_MGMT_1::SLEEP)? != 0)
253 }
254
255 pub fn set_temp_enabled(&mut self, enable: bool) -> Result<(), Mpu6886Error<E>> {
259 Ok(self.write_bit(PWR_MGMT_1::ADDR, PWR_MGMT_1::TEMP_DIS, !enable)?)
260 }
261
262 pub fn get_temp_enabled(&mut self) -> Result<bool, Mpu6886Error<E>> {
266 Ok(self.read_bit(PWR_MGMT_1::ADDR, PWR_MGMT_1::TEMP_DIS)? == 0)
267 }
268
269 pub fn set_accel_x_self_test(&mut self, enable: bool) -> Result<(), Mpu6886Error<E>> {
271 Ok(self.write_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::XA_ST, enable)?)
272 }
273
274 pub fn get_accel_x_self_test(&mut self) -> Result<bool, Mpu6886Error<E>> {
276 Ok(self.read_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::XA_ST)? != 0)
277 }
278
279 pub fn set_accel_y_self_test(&mut self, enable: bool) -> Result<(), Mpu6886Error<E>> {
281 Ok(self.write_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::YA_ST, enable)?)
282 }
283
284 pub fn get_accel_y_self_test(&mut self) -> Result<bool, Mpu6886Error<E>> {
286 Ok(self.read_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::YA_ST)? != 0)
287 }
288
289 pub fn set_accel_z_self_test(&mut self, enable: bool) -> Result<(), Mpu6886Error<E>> {
291 Ok(self.write_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::ZA_ST, enable)?)
292 }
293
294 pub fn get_accel_z_self_test(&mut self) -> Result<bool, Mpu6886Error<E>> {
296 Ok(self.read_bit(ACCEL_CONFIG::ADDR, ACCEL_CONFIG::ZA_ST)? != 0)
297 }
298
299 pub fn get_acc_angles(&mut self) -> Result<Vector2<f32>, Mpu6886Error<E>> {
303 let acc = self.get_acc()?;
304
305 Ok(Vector2::<f32>::new(
306 atan2f(acc.y, sqrtf(powf(acc.x, 2.) + powf(acc.z, 2.))),
307 atan2f(-acc.x, sqrtf(powf(acc.y, 2.) + powf(acc.z, 2.)))
308 ))
309 }
310
311 fn read_word_2c(&self, byte: &[u8]) -> i32 {
314 let high: i32 = byte[0] as i32;
315 let low: i32 = byte[1] as i32;
316 let mut word: i32 = (high << 8) + low;
317
318 if word >= 0x8000 {
319 word = -((65535 - word) + 1);
320 }
321
322 word
323 }
324
325 fn read_rot(&mut self, reg: u8) -> Result<Vector3<f32>, Mpu6886Error<E>> {
327 let mut buf: [u8; 6] = [0; 6];
328 self.read_bytes(reg, &mut buf)?;
329
330 Ok(Vector3::<f32>::new(
331 self.read_word_2c(&buf[0..2]) as f32,
332 self.read_word_2c(&buf[2..4]) as f32,
333 self.read_word_2c(&buf[4..6]) as f32
334 ))
335 }
336
337 pub fn get_acc(&mut self) -> Result<Vector3<f32>, Mpu6886Error<E>> {
339 let mut acc = self.read_rot(ACC_REGX_H)?;
340 acc /= self.acc_sensitivity;
341
342 Ok(acc)
343 }
344
345 pub fn get_gyro(&mut self) -> Result<Vector3<f32>, Mpu6886Error<E>> {
347 let mut gyro = self.read_rot(GYRO_REGX_H)?;
348
349 gyro *= PI_180 / self.gyro_sensitivity;
350
351 Ok(gyro)
352 }
353
354 pub fn get_temp(&mut self) -> Result<f32, Mpu6886Error<E>> {
356 let mut buf: [u8; 2] = [0; 2];
357 self.read_bytes(TEMP_OUT_H, &mut buf)?;
358 let raw_temp = self.read_word_2c(&buf[0..2]) as f32;
359
360 Ok((raw_temp / TEMP_SENSITIVITY) + TEMP_OFFSET)
362 }
363
364 pub fn write_byte(&mut self, reg: u8, byte: u8) -> Result<(), Mpu6886Error<E>> {
366 self.i2c.write(self.slave_addr, &[reg, byte])
367 .map_err(Mpu6886Error::I2c)?;
368 Ok(())
372 }
373
374 pub fn write_bit(&mut self, reg: u8, bit_n: u8, enable: bool) -> Result<(), Mpu6886Error<E>> {
376 let mut byte: [u8; 1] = [0; 1];
377 self.read_bytes(reg, &mut byte)?;
378 bits::set_bit(&mut byte[0], bit_n, enable);
379 Ok(self.write_byte(reg, byte[0])?)
380 }
381
382 pub fn write_bits(&mut self, reg: u8, start_bit: u8, length: u8, data: u8) -> Result<(), Mpu6886Error<E>> {
384 let mut byte: [u8; 1] = [0; 1];
385 self.read_bytes(reg, &mut byte)?;
386 bits::set_bits(&mut byte[0], start_bit, length, data);
387 Ok(self.write_byte(reg, byte[0])?)
388 }
389
390 fn read_bit(&mut self, reg: u8, bit_n: u8) -> Result<u8, Mpu6886Error<E>> {
392 let mut byte: [u8; 1] = [0; 1];
393 self.read_bytes(reg, &mut byte)?;
394 Ok(bits::get_bit(byte[0], bit_n))
395 }
396
397 pub fn read_bits(&mut self, reg: u8, start_bit: u8, length: u8) -> Result<u8, Mpu6886Error<E>> {
399 let mut byte: [u8; 1] = [0; 1];
400 self.read_bytes(reg, &mut byte)?;
401 Ok(bits::get_bits(byte[0], start_bit, length))
402 }
403
404 pub fn read_byte(&mut self, reg: u8) -> Result<u8, Mpu6886Error<E>> {
406 let mut byte: [u8; 1] = [0; 1];
407 self.i2c.write_read(self.slave_addr, &[reg], &mut byte)
408 .map_err(Mpu6886Error::I2c)?;
409 Ok(byte[0])
410 }
411
412 pub fn read_bytes(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Mpu6886Error<E>> {
414 self.i2c.write_read(self.slave_addr, &[reg], buf)
415 .map_err(Mpu6886Error::I2c)?;
416 Ok(())
417 }
418}
419