From b6ea8e34fa6a80a4f5b7a89561e1141a8bd4c35a Mon Sep 17 00:00:00 2001 From: Sachymetsu Date: Mon, 11 May 2026 09:50:15 +0200 Subject: [PATCH] Expose error mode of AdcDriver --- embassy-strike-driver/Cargo.toml | 2 +- embassy-strike-driver/src/drivers.rs | 24 ++++++++++++++---------- embassy-strike-driver/src/lib.rs | 27 ++++++++++++++++----------- embassy-strike-driver/src/traits.rs | 6 ++++-- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/embassy-strike-driver/Cargo.toml b/embassy-strike-driver/Cargo.toml index 1fde6fe..0e3f77e 100644 --- a/embassy-strike-driver/Cargo.toml +++ b/embassy-strike-driver/Cargo.toml @@ -8,7 +8,7 @@ license.workspace = true rust-version.workspace = true [features] -default = [] +default = ["rp2040"] debug = ["defmt"] alloc = [] heapless = ["dep:heapless"] diff --git a/embassy-strike-driver/src/drivers.rs b/embassy-strike-driver/src/drivers.rs index f6fd2e8..7ed8528 100644 --- a/embassy-strike-driver/src/drivers.rs +++ b/embassy-strike-driver/src/drivers.rs @@ -23,23 +23,25 @@ pub mod rp { } impl AdcInner<'_> { - /// Samples at 100Khz, or 10us per sample. If a sampling fails due to conversion error, + /// Samples at 200Khz, or 5us per sample. If a sampling fails due to conversion error, /// it tries again until the sampling succeeds. - async fn read_many(&mut self, buf: &mut [u16]) { + async fn read_many(&mut self, buf: &mut [u16]) -> Result<(), adc::Error> { let mut retries: u32 = 5; - while self + // We will retry this operation a few times before bubbling up the error. + while let Err(e) = self .adc .read_many(&mut self.pin, buf, 240, &mut self.dma) .await - .is_err() { retries -= 1; if retries == 0 { - panic!("ADC not configured or connected correctly."); + return Err(e); } } + + Ok(()) } } @@ -63,16 +65,18 @@ pub mod rp { } impl<'device, M: RawMutex> AdcSource for AdcDriver<'device, M> { - async fn sample_average(&self, samples: &mut [u16]) -> u16 { - self.sample(samples).await; + type Error = adc::Error; + + async fn sample_average(&self, samples: &mut [u16]) -> Result { + self.sample(samples).await?; let len = samples.len() as u32; - (samples.iter().copied().map(u32::from).sum::() / len) as u16 + Ok((samples.iter().copied().map(u32::from).sum::() / len) as u16) } - async fn sample(&self, samples: &mut [u16]) { - self.inner.lock().await.read_many(samples).await; + async fn sample(&self, samples: &mut [u16]) -> Result<(), Self::Error> { + self.inner.lock().await.read_many(samples).await } } diff --git a/embassy-strike-driver/src/lib.rs b/embassy-strike-driver/src/lib.rs index c7be5de..ebffd13 100644 --- a/embassy-strike-driver/src/lib.rs +++ b/embassy-strike-driver/src/lib.rs @@ -148,12 +148,12 @@ where self.config.clone() } - pub async fn tune(&mut self, samples: &mut [u16]) { + pub async fn tune(&mut self, samples: &mut [u16]) -> Result<(), A::Error> { let mut duty = 0; let max_duty = self.pwm.max_duty(); self.pwm.set_duty(duty); Timer::after_secs(2).await; - let mut act_value = self.adc.sample_average(samples).await; + let mut act_value = self.adc.sample_average(samples).await?; #[cfg(feature = "debug")] info!("START: {}", act_value); @@ -165,12 +165,12 @@ where duty = 0; self.pwm.set_duty(duty); Timer::after_secs(2).await; - act_value = self.adc.sample_average(samples).await; + act_value = self.adc.sample_average(samples).await?; continue; } self.pwm.set_duty(duty); Timer::after_millis(250).await; - act_value = self.adc.sample_average(samples).await; + act_value = self.adc.sample_average(samples).await?; #[cfg(feature = "debug")] info!("UPDATE: {} @ Duty {}", act_value, duty); } @@ -180,20 +180,22 @@ where self.state.duty.set(duty as u8); // Allow voltage level to stabilize after tuning Timer::after_secs(2).await; - let avg = self.adc.sample_average(samples).await; + let avg = self.adc.sample_average(samples).await?; #[cfg(feature = "debug")] info!("SET: {} @ Duty {}/{}", avg, duty, self.state.max_duty.get()); self.state.avg.set(avg); + + Ok(()) } /// Samples and returns an `i64` timestamp. pub async fn sample_with_zerocopy<'a>( &self, dma: &mut Sender<'a, NoopRawMutex, (i64, [u16; BLOCK_SIZE])>, - ) { + ) -> Result<(), A::Error> { loop { let (time, samples) = dma.send().await; - self.adc.sample(samples).await; + self.adc.sample(samples).await?; *time = self.get_timestamp(); dma.send_done(); } @@ -335,12 +337,15 @@ mod tests { struct MockAdc<'a>(&'a MockMachine); impl AdcSource for MockAdc<'_> { - async fn sample(&self, samples: &mut [u16]) { + type Error = core::convert::Infallible; + + async fn sample(&self, samples: &mut [u16]) -> Result<(), Self::Error> { samples.fill(self.0.adc_sample_avg()); + Ok(()) } - async fn sample_average(&self, _samples: &mut [u16]) -> u16 { - self.0.adc_sample_avg() + async fn sample_average(&self, _samples: &mut [u16]) -> Result { + Ok(self.0.adc_sample_avg()) } } @@ -463,7 +468,7 @@ mod tests { assert_eq!(detector.state.max_duty.get(), 108); assert_eq!(detector.state.duty.get(), 90); - assert_eq!(detector.adc.sample_average(&mut buf).await, 1260); + assert_eq!(detector.adc.sample_average(&mut buf).await.unwrap(), 1260); } #[pollster::test] diff --git a/embassy-strike-driver/src/traits.rs b/embassy-strike-driver/src/traits.rs index c3c9d77..06f26ae 100644 --- a/embassy-strike-driver/src/traits.rs +++ b/embassy-strike-driver/src/traits.rs @@ -6,8 +6,10 @@ pub trait TimeSource { } pub trait AdcSource { - fn sample_average(&self, samples: &mut [u16]) -> impl Future; - fn sample(&self, samples: &mut [u16]) -> impl Future; + type Error; + + fn sample_average(&self, samples: &mut [u16]) -> impl Future>; + fn sample(&self, samples: &mut [u16]) -> impl Future>; } pub trait PwmSource { -- 2.51.2