variegated_nau7802/
lib.rs1#![no_std]
40#![warn(missing_docs)]
41
42use byteorder::ByteOrder as _;
43use core::{fmt, slice};
44use embedded_hal_async::digital::Wait;
45use embedded_hal_async::i2c::I2c;
46use embedded_hal_async::delay::DelayNs;
47
48mod constants;
49pub use constants::*;
50
51pub type Result<T> = core::result::Result<T, Error>;
53
54#[derive(Debug)]
56pub enum Error {
57 I2cError,
59 PowerupFailed,
61}
62
63pub enum Nau7802DataAvailableStrategy<W: Wait>{
65 Polling,
67 DrdyPin(W),
69}
70
71pub struct Nau7802<I2C: I2c, W: Wait, D: DelayNs> {
73 i2c: I2C,
74 address: u8,
75 wait_strategy: Nau7802DataAvailableStrategy<W>,
76 delay: D
77}
78
79impl<I2C: I2c, W: Wait, D: DelayNs> Nau7802<I2C, W, D>
80where
81 I2C::Error: fmt::Debug,
82{
83 pub fn new(i2c: I2C, wait_strategy: Nau7802DataAvailableStrategy<W>, delay: D, address: Option<u8>) -> Self {
85 let addr = if let Some(a) = address {
86 a
87 } else {
88 0x2A
89 };
90
91 Self {
92 i2c,
93 wait_strategy,
94 delay,
95 address: addr
96 }
97 }
98
99 pub async fn init(
101 &mut self,
102 ldo: Ldo,
103 gain: Gain,
104 sps: SamplesPerSecond,
105 ) -> Result<()> {
106 self.start_reset().await?;
107 self.finish_reset().await?;
108 self.power_up().await?;
109 self.set_ldo(ldo).await?;
110 self.set_gain(gain).await?;
111 self.set_sample_rate(sps).await?;
112 self.misc_init().await?;
113 self.begin_afe_calibration().await?;
114
115 while self.poll_afe_calibration_status().await? != AfeCalibrationStatus::Success {}
116
117 Ok(())
118 }
119
120 pub async fn wait_for_data_available(&mut self) -> Result<()> {
122 match self.wait_strategy {
123 Nau7802DataAvailableStrategy::Polling => self.wait_for_data_available_i2c().await?,
124 Nau7802DataAvailableStrategy::DrdyPin(ref mut w) => w.wait_for_high().await.map_err(|_| Error::I2cError)?
125 }
126
127 Ok(())
128 }
129
130 async fn wait_for_data_available_i2c(&mut self) -> Result<()> {
131 loop {
132 if self.get_bit(Register::PuCtrl, PuCtrlBits::CR).await? {
133 return Ok(());
134 }
135 self.delay.delay_ms(1).await;
136 }
137 }
138
139 pub async fn read(&mut self) -> Result<i32> {
141 self.wait_for_data_available().await?;
142
143 self.request_register(Register::AdcoB2).await?;
144
145 let mut buf = [0u8; 3]; self.i2c
147 .read(self.address, &mut buf)
148 .await
149 .map_err(|_| Error::I2cError)?;
150
151 let adc_result = byteorder::BigEndian::read_i24(&buf);
152 Ok(adc_result)
153 }
154
155 pub async fn begin_afe_calibration(&mut self) -> Result<()> {
157 self.set_bit(Register::Ctrl2, Ctrl2RegisterBits::Cals).await
158 }
159
160 pub async fn poll_afe_calibration_status(&mut self) -> Result<AfeCalibrationStatus> {
162 if self.get_bit(Register::Ctrl2, Ctrl2RegisterBits::Cals).await? {
163 return Ok(AfeCalibrationStatus::InProgress);
164 }
165
166 if self.get_bit(Register::Ctrl2, Ctrl2RegisterBits::CalError).await? {
167 return Ok(AfeCalibrationStatus::Failure);
168 }
169
170 Ok(AfeCalibrationStatus::Success)
171 }
172
173 pub async fn set_sample_rate(&mut self, sps: SamplesPerSecond) -> Result<()> {
175 const SPS_MASK: u8 = 0b10001111;
176 const SPS_START_BIT_IDX: u8 = 4;
177
178 self.set_function_helper(Register::Ctrl2, SPS_MASK, SPS_START_BIT_IDX, sps as _).await
179 }
180
181 pub async fn set_gain(&mut self, gain: Gain) -> Result<()> {
183 const GAIN_MASK: u8 = 0b11111000;
184 const GAIN_START_BIT: u8 = 0;
185
186 self.set_function_helper(Register::Ctrl1, GAIN_MASK, GAIN_START_BIT, gain as _).await
187 }
188
189 pub async fn set_ldo(&mut self, ldo: Ldo) -> Result<()> {
191 const LDO_MASK: u8 = 0b11000111;
192 const LDO_START_BIT: u8 = 3;
193
194 self.set_function_helper(Register::Ctrl1, LDO_MASK, LDO_START_BIT, ldo as _).await?;
195
196 self.set_bit(Register::PuCtrl, PuCtrlBits::AVDDS).await
197 }
198
199 pub async fn power_up(&mut self) -> Result<()> {
201 const NUM_ATTEMPTS: usize = 100;
202
203 self.set_bit(Register::PuCtrl, PuCtrlBits::PUD).await?;
204 self.set_bit(Register::PuCtrl, PuCtrlBits::PUA).await?;
205
206 let mut powered_up = false;
207 let mut attempts = 0;
208 while !powered_up && attempts < NUM_ATTEMPTS {
209 let res = self.get_bit(Register::PuCtrl, PuCtrlBits::PUR).await;
210 if let Ok(rdy) = res {
211 powered_up = rdy;
212 }
213
214 attempts += 1;
215 }
216
217 if powered_up {
218 Ok(())
219 } else {
220 Err(Error::PowerupFailed)
221 }
222 }
223
224 pub async fn start_reset(&mut self) -> Result<()> {
226 self.set_bit(Register::PuCtrl, PuCtrlBits::RR).await
227 }
228
229 pub async fn finish_reset(&mut self) -> Result<()> {
231 self.clear_bit(Register::PuCtrl, PuCtrlBits::RR).await
232 }
233
234
235 pub async fn misc_init(&mut self) -> Result<()> {
237 const TURN_OFF_CLK_CHPL: u8 = 0x30;
238
239 self.set_register(Register::Adc, TURN_OFF_CLK_CHPL).await?;
241
242 self.set_bit(Register::PgaPwr, PgaPwrRegisterBits::CapEn).await
244 }
245
246 async fn set_function_helper(
247 &mut self,
248 reg: Register,
249 mask: u8,
250 start_idx: u8,
251 new_val: u8,
252 ) -> Result<()> {
253 let mut val = self.get_register(reg).await?;
254 val &= mask;
255 val |= new_val << start_idx;
256
257 self.set_register(reg, val).await
258 }
259
260 async fn set_bit<B: RegisterBits>(&mut self, addr: Register, bit_idx: B) -> Result<()> {
261 let mut val = self.get_register(addr).await?;
262 val |= 1 << bit_idx.get();
263 self.set_register(addr, val).await
264 }
265
266 async fn clear_bit<B: RegisterBits>(&mut self, addr: Register, bit_idx: B) -> Result<()> {
267 let mut val = self.get_register(addr).await?;
268 val &= !(1 << bit_idx.get());
269 self.set_register(addr, val).await
270 }
271
272 async fn get_bit<B: RegisterBits>(&mut self, addr: Register, bit_idx: B) -> Result<bool> {
273 let mut val = self.get_register(addr).await?;
274 val &= 1 << bit_idx.get();
275 Ok(val != 0)
276 }
277
278 async fn set_register(&mut self, reg: Register, val: u8) -> Result<()> {
279 let transaction = [reg as _, val];
280
281 self.i2c
282 .write(self.address, &transaction)
283 .await
284 .map_err(|_| Error::I2cError)
285 }
286
287 async fn get_register(&mut self, reg: Register) -> Result<u8> {
288 self.request_register(reg).await?;
289
290 let mut val = 0;
291 self.i2c
292 .read(self.address, slice::from_mut(&mut val))
293 .await
294 .map_err(|_| Error::I2cError)?;
295
296 Ok(val)
297 }
298
299 async fn request_register(&mut self, reg: Register) -> Result<()> {
300 let reg = reg as u8;
301
302 self.i2c
303 .write(self.address, slice::from_ref(®))
304 .await
305 .map_err(|_| Error::I2cError)
306 }
307}