1#![no_std]
54
55mod conf;
56mod register;
57
58use core::fmt::Debug;
59
60use embedded_hal as hal;
61
62use hal::blocking::spi;
63use hal::digital::v2::OutputPin;
64
65pub use accelerometer::{Accelerometer, RawAccelerometer, error, Error, vector::{I32x3, F32x3}};
66
67pub use conf::*;
68use register::Register;
69
70const SPI_READ: u8 = 0x01;
71const SPI_WRITE: u8 = 0x00;
72
73const EXPECTED_DEVICE_ID: u8 = 0xED;
74
75const ACCEL_MAX_I20: u32 = 524_287; pub struct Adxl355<SPI, CS> {
80 spi: SPI,
81 cs: CS,
82
83 odr: ODR_LPF,
85 hpf: HPF_CORNER,
86 range: Range,
87}
88
89
90impl<SPI, CS, E, PinError> Adxl355<SPI, CS>
91where
92 SPI: spi::Transfer<u8, Error=E> + spi::Write<u8, Error=E>,
93 CS: OutputPin<Error = PinError>
94{
95
96
97 pub fn default(spi:SPI, cs:CS) -> Result<Self, E> {
100 Adxl355::new(spi, cs, &Config::new())
101 }
102
103 pub fn new(spi:SPI, cs:CS, config: &Config) -> Result<Self, E> {
105 let mut adxl355 = Adxl355 {
106 spi,
107 cs,
108 odr: config.odr.unwrap_or_default(),
109 hpf: config.hpf.unwrap_or_default(),
110 range: config.range.unwrap_or_default()
111 };
112
113
114 let id = adxl355.get_device_id();
115
116 if id != EXPECTED_DEVICE_ID {
117 }
120
121 adxl355.write_reg(Register::FILTER.addr(), (adxl355.hpf.val() << 4) | adxl355.odr.val());
122 adxl355.write_reg(Register::RANGE.addr(), adxl355.range.val());
123
124 Ok(adxl355)
125 }
126
127 pub fn start(&mut self) {
129 self.write_reg(Register::POWER_CTL.addr(), 0);
130 }
131
132
133 pub fn read_temp_raw(&mut self) -> u16 {
135
136 let mut bytes = [(Register::TEMP2.addr() << 1) | SPI_READ, 0, 0];
137 self.read(&mut bytes);
138
139 let temp_h = ((bytes[1] & 0x0F) as u16) << 8;
140 let temp_l = (bytes[2] as u16) & 0x00FF;
141
142 temp_h | temp_l
143 }
144
145 pub fn get_device_id(&mut self) -> u8 {
147 let reg = Register::DEVID.addr();
148 let mut output = [1u8];
149 self.read_reg(reg, &mut output);
150 output[0]
151 }
152
153 fn write_reg(&mut self, reg: u8, value: u8) {
154 let mut bytes = [(reg << 1) | SPI_WRITE, value];
155 self.cs.set_low().ok();
156 self.spi.write(&mut bytes).ok();
157 self.cs.set_high().ok();
158 }
159
160 fn read_reg(&mut self, reg: u8, buffer: &mut [u8]) {
161 let mut bytes = [(reg << 1) | SPI_READ, 0];
162 self.cs.set_low().ok();
163 self.spi.transfer(&mut bytes).ok();
164 self.cs.set_high().ok();
165 buffer[0] = bytes[1];
166 }
167
168 fn read(&mut self, bytes: &mut [u8]) {
169 self.cs.set_low().ok();
170 self.spi.transfer(bytes).ok();
171 self.cs.set_high().ok();
172 }
173}
174
175impl<SPI, CS, E, EO> RawAccelerometer<I32x3> for Adxl355<SPI, CS>
176where
177 SPI: spi::Transfer<u8, Error=E> + spi::Write<u8, Error=E>,
178 CS: OutputPin<Error = EO>,
179 E: Debug
180{
181 type Error = E;
182
183 fn accel_raw(&mut self) -> Result<I32x3, Error<E>> {
186 let mut bytes = [0u8; 9+1];
187 bytes[0] = (Register::XDATA3.addr() << 1) | SPI_READ;
188 self.read(&mut bytes);
189
190 let x = ((((bytes[1] as i32) << 24) | ((bytes[2] as i32) << 16) | ((bytes[3] & 0xF0) as i32) << 8)) >> 12;
193 let y = ((((bytes[4] as i32) << 24) | ((bytes[5] as i32) << 16) | ((bytes[6] & 0xF0) as i32) << 8)) >> 12;
194 let z = ((((bytes[7] as i32) << 24) | ((bytes[8] as i32) << 16) | ((bytes[9] & 0xF0) as i32) << 8)) >> 12;
195
196 Ok(I32x3::new(x, y, z))
197 }
198
199}
200
201impl<SPI, CS, E, PinError> Accelerometer for Adxl355<SPI, CS>
202where
203 SPI: spi::Transfer<u8, Error=E> + spi::Write<u8, Error=E>,
204 CS: OutputPin<Error = PinError>,
205 E: Debug
206{
207 type Error = E;
208
209 fn sample_rate(&mut self) -> Result<f32, Error<Self::Error>> {
210 Ok(self.odr.into())
211 }
212
213 fn accel_norm(&mut self) -> Result<F32x3, Error<Self::Error>> {
214 let raw_data: I32x3 = self.accel_raw()?;
215 let range: f32 = self.range.into(); let x = (raw_data.x as f32 / ACCEL_MAX_I20 as f32) * range;
218 let y = (raw_data.y as f32 / ACCEL_MAX_I20 as f32) * range;
219 let z = (raw_data.z as f32 / ACCEL_MAX_I20 as f32) * range;
220
221 Ok(F32x3::new(x, y, z))
222 }
223}