1#![deny(warnings)]
14#![no_std]
15
16#[path = "."]
17#[allow(clippy::duplicate_mod)]
18pub mod asynchronous {
20 use bisync::asynchronous::*;
21 pub mod i2c;
23 pub mod spi;
25}
26
27#[path = "."]
29pub mod blocking {
31 use bisync::synchronous::*;
32 pub mod i2c;
34 pub mod spi;
36}
37
38pub use blocking::*;
40
41pub const MINIMUM_CS_SETUP_TIME_NS: u32 = 5;
43
44pub const WHO_AM_I_L3GD20: u8 = 0xD4;
46pub const WHO_AM_I_L3GD20H: u8 = 0xD7;
48
49pub trait BitValue {
51 fn width() -> u8;
53 fn mask() -> u8 {
55 (1 << Self::width()) - 1
56 }
57 fn shift() -> u8;
59 fn value(&self) -> u8;
64}
65
66#[allow(dead_code)]
67#[allow(non_camel_case_types)]
68#[allow(clippy::upper_case_acronyms)]
69#[derive(Clone, Copy)]
70#[cfg_attr(feature = "defmt", derive(defmt::Format))]
71pub enum Register {
72 WHO_AM_I = 0x0F,
73 CTRL_REG1 = 0x20,
74 CTRL_REG2 = 0x21,
75 CTRL_REG3 = 0x22,
76 CTRL_REG4 = 0x23,
77 CTRL_REG5 = 0x24,
78 REFERENCE = 0x25,
79 OUT_TEMP = 0x26,
80 STATUS_REG = 0x27,
81 OUT_X_L = 0x28,
82 OUT_X_H = 0x29,
83 OUT_Y_L = 0x2A,
84 OUT_Y_H = 0x2B,
85 OUT_Z_L = 0x2C,
86 OUT_Z_H = 0x2D,
87 FIFO_CTRL_REG = 0x2E,
88 FIFO_SRC_REG = 0x2F,
89 INT1_CFG = 0x30,
90 INT1_SRC = 0x31,
91 INT1_TSH_XH = 0x32,
92 INT1_TSH_XL = 0x33,
93 INT1_TSH_YH = 0x34,
94 INT1_TSH_YL = 0x35,
95 INT1_TSH_ZH = 0x36,
96 INT1_TSH_ZL = 0x37,
97 INT1_DURATION = 0x38,
98}
99
100#[derive(Debug, Clone, Copy)]
102#[cfg_attr(feature = "defmt", derive(defmt::Format))]
103pub enum Odr {
104 Hz95 = 0x00,
106 Hz190 = 0x01,
108 Hz380 = 0x02,
110 Hz760 = 0x03,
112}
113
114impl BitValue for Odr {
115 fn width() -> u8 {
116 2
117 }
118 fn shift() -> u8 {
119 6
120 }
121 fn value(&self) -> u8 {
122 *self as u8
123 }
124}
125
126impl Odr {
127 fn from_u8(from: u8) -> Self {
128 match (from >> Odr::shift()) & Odr::mask() {
130 x if x == Odr::Hz95 as u8 => Odr::Hz95,
131 x if x == Odr::Hz190 as u8 => Odr::Hz190,
132 x if x == Odr::Hz380 as u8 => Odr::Hz380,
133 x if x == Odr::Hz760 as u8 => Odr::Hz760,
134 _ => unreachable!(),
135 }
136 }
137}
138
139#[derive(Debug, Clone, Copy)]
141#[cfg_attr(feature = "defmt", derive(defmt::Format))]
142pub enum Scale {
143 Dps250 = 0x00,
145 Dps500 = 0x01,
147 Dps2000 = 0x03,
149}
150
151impl BitValue for Scale {
152 fn width() -> u8 {
153 2
154 }
155 fn shift() -> u8 {
156 4
157 }
158 fn value(&self) -> u8 {
159 *self as u8
160 }
161}
162
163impl Scale {
164 fn from_u8(from: u8) -> Self {
165 match (from >> Scale::shift()) & Scale::mask() {
168 x if x == Scale::Dps250 as u8 => Scale::Dps250,
169 x if x == Scale::Dps500 as u8 => Scale::Dps500,
170 x if x == Scale::Dps2000 as u8 => Scale::Dps2000,
171 0x02 => Scale::Dps2000,
173 _ => unreachable!(),
174 }
175 }
176}
177
178#[derive(Debug, Clone, Copy)]
184#[cfg_attr(feature = "defmt", derive(defmt::Format))]
185pub enum Bandwidth {
186 Low = 0x00,
188 Medium = 0x01,
190 High = 0x02,
192 Maximum = 0x03,
194}
195
196impl BitValue for Bandwidth {
197 fn width() -> u8 {
198 2
199 }
200 fn shift() -> u8 {
201 4
202 }
203 fn value(&self) -> u8 {
204 *self as u8
205 }
206}
207
208impl Bandwidth {
209 fn from_u8(from: u8) -> Self {
210 match (from >> Bandwidth::shift()) & Bandwidth::mask() {
212 x if x == Bandwidth::Low as u8 => Bandwidth::Low,
213 x if x == Bandwidth::Medium as u8 => Bandwidth::Medium,
214 x if x == Bandwidth::High as u8 => Bandwidth::High,
215 x if x == Bandwidth::Maximum as u8 => Bandwidth::Maximum,
216 _ => unreachable!(),
217 }
218 }
219}
220
221impl Register {
222 fn addr(self) -> u8 {
223 self as u8
224 }
225}
226
227impl Scale {
228 pub fn degrees(&self, val: i16) -> f32 {
230 match *self {
231 Scale::Dps250 => val as f32 * 0.00875,
232 Scale::Dps500 => val as f32 * 0.0175,
233 Scale::Dps2000 => val as f32 * 0.07,
234 }
235 }
236
237 pub fn radians(&self, val: i16) -> f32 {
239 self.degrees(val) * (core::f32::consts::PI / 180.0)
242 }
243}
244
245#[derive(Debug, Clone, Copy)]
247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
248pub struct I16x3 {
249 pub x: i16,
251 pub y: i16,
253 pub z: i16,
255}
256
257#[derive(Debug, Clone, Copy)]
259#[cfg_attr(feature = "defmt", derive(defmt::Format))]
260pub struct Measurements {
261 pub gyro: I16x3,
263 pub temp_raw: i8,
265}
266
267impl Measurements {
268 pub fn temp_celcius(&self) -> i16 {
270 25 - self.temp_raw as i16
271 }
272}
273
274#[derive(Debug, Clone, Copy)]
276#[cfg_attr(feature = "defmt", derive(defmt::Format))]
277pub struct Status {
278 pub overrun: bool,
281 pub z_overrun: bool,
283 pub y_overrun: bool,
285 pub x_overrun: bool,
287 pub new_data: bool,
289 pub z_new: bool,
291 pub y_new: bool,
293 pub x_new: bool,
295}
296
297impl Status {
298 fn from_u8(from: u8) -> Self {
299 Status {
300 overrun: (from & (1 << 7)) != 0,
301 z_overrun: (from & (1 << 6)) != 0,
302 y_overrun: (from & (1 << 5)) != 0,
303 x_overrun: (from & (1 << 4)) != 0,
304 new_data: (from & (1 << 3)) != 0,
305 z_new: (from & (1 << 2)) != 0,
306 y_new: (from & (1 << 1)) != 0,
307 x_new: (from & 1) != 0,
308 }
309 }
310}