aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-12-04 02:11:16 +0100
committerDario Nieuwenhuis <[email protected]>2025-12-04 02:11:16 +0100
commite98694606d556d611400dcaf96844343bed2c5f7 (patch)
treeb514446f78e6e309d76eebb5c51cd442a7720f2d
parent201502e308564a233bf3649b1a974d5d4374bd96 (diff)
stm32/adc: add lifetime to AnyAdcChannel.
-rw-r--r--embassy-stm32/src/adc/g4.rs18
-rw-r--r--embassy-stm32/src/adc/injected.rs10
-rw-r--r--embassy-stm32/src/adc/mod.rs27
3 files changed, 29 insertions, 26 deletions
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 1767a3bb3..d4e526061 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -409,10 +409,10 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
409 /// `InjectedAdc<T, N>` to enforce bounds at compile time. 409 /// `InjectedAdc<T, N>` to enforce bounds at compile time.
410 pub fn setup_injected_conversions<'a, const N: usize>( 410 pub fn setup_injected_conversions<'a, const N: usize>(
411 self, 411 self,
412 sequence: [(AnyAdcChannel<T>, SampleTime); N], 412 sequence: [(AnyAdcChannel<'a, T>, SampleTime); N],
413 trigger: ConversionTrigger, 413 trigger: ConversionTrigger,
414 interrupt: bool, 414 interrupt: bool,
415 ) -> InjectedAdc<T, N> { 415 ) -> InjectedAdc<'a, T, N> {
416 assert!(N != 0, "Read sequence cannot be empty"); 416 assert!(N != 0, "Read sequence cannot be empty");
417 assert!( 417 assert!(
418 N <= NR_INJECTED_RANKS, 418 N <= NR_INJECTED_RANKS,
@@ -424,8 +424,8 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
424 424
425 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1)); 425 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1));
426 426
427 for (n, (channel, sample_time)) in sequence.into_iter().enumerate() { 427 for (n, (channel, sample_time)) in sequence.iter().enumerate() {
428 let sample_time = sample_time.into(); 428 let sample_time = sample_time.clone().into();
429 if channel.channel() <= 9 { 429 if channel.channel() <= 9 {
430 T::regs() 430 T::regs()
431 .smpr() 431 .smpr()
@@ -487,16 +487,16 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
487 /// This function is `unsafe` because it clones the ADC peripheral handle unchecked. Both the 487 /// This function is `unsafe` because it clones the ADC peripheral handle unchecked. Both the
488 /// `RingBufferedAdc` and `InjectedAdc` take ownership of the handle and drop it independently. 488 /// `RingBufferedAdc` and `InjectedAdc` take ownership of the handle and drop it independently.
489 /// Ensure no other code concurrently accesses the same ADC instance in a conflicting way. 489 /// Ensure no other code concurrently accesses the same ADC instance in a conflicting way.
490 pub fn into_ring_buffered_and_injected<'a, const N: usize>( 490 pub fn into_ring_buffered_and_injected<'a, 'b, const N: usize>(
491 self, 491 self,
492 dma: Peri<'a, impl RxDma<T>>, 492 dma: Peri<'a, impl RxDma<T>>,
493 dma_buf: &'a mut [u16], 493 dma_buf: &'a mut [u16],
494 regular_sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, T::SampleTime)>, 494 regular_sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, T::SampleTime)>,
495 regular_conversion_mode: RegularConversionMode, 495 regular_conversion_mode: RegularConversionMode,
496 injected_sequence: [(AnyAdcChannel<T>, SampleTime); N], 496 injected_sequence: [(AnyAdcChannel<'b, T>, SampleTime); N],
497 injected_trigger: ConversionTrigger, 497 injected_trigger: ConversionTrigger,
498 injected_interrupt: bool, 498 injected_interrupt: bool,
499 ) -> (super::RingBufferedAdc<'a, T>, InjectedAdc<T, N>) { 499 ) -> (super::RingBufferedAdc<'a, T>, InjectedAdc<'b, T, N>) {
500 unsafe { 500 unsafe {
501 ( 501 (
502 Self { 502 Self {
@@ -531,7 +531,7 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
531 } 531 }
532} 532}
533 533
534impl<T: Instance, const N: usize> InjectedAdc<T, N> { 534impl<'a, T: Instance, const N: usize> InjectedAdc<'a, T, N> {
535 /// Read sampled data from all injected ADC injected ranks 535 /// Read sampled data from all injected ADC injected ranks
536 /// Clear the JEOS flag to allow a new injected sequence 536 /// Clear the JEOS flag to allow a new injected sequence
537 pub(super) fn read_injected_data() -> [u16; N] { 537 pub(super) fn read_injected_data() -> [u16; N] {
diff --git a/embassy-stm32/src/adc/injected.rs b/embassy-stm32/src/adc/injected.rs
index ccaa5d1b2..1af055644 100644
--- a/embassy-stm32/src/adc/injected.rs
+++ b/embassy-stm32/src/adc/injected.rs
@@ -10,13 +10,13 @@ use crate::adc::Instance;
10use crate::adc::{Adc, AnyInstance}; 10use crate::adc::{Adc, AnyInstance};
11 11
12/// Injected ADC sequence with owned channels. 12/// Injected ADC sequence with owned channels.
13pub struct InjectedAdc<T: Instance, const N: usize> { 13pub struct InjectedAdc<'a, T: Instance, const N: usize> {
14 _channels: [(AnyAdcChannel<T>, SampleTime); N], 14 _channels: [(AnyAdcChannel<'a, T>, SampleTime); N],
15 _phantom: PhantomData<T>, 15 _phantom: PhantomData<T>,
16} 16}
17 17
18impl<T: Instance, const N: usize> InjectedAdc<T, N> { 18impl<'a, T: Instance, const N: usize> InjectedAdc<'a, T, N> {
19 pub(crate) fn new(channels: [(AnyAdcChannel<T>, SampleTime); N]) -> Self { 19 pub(crate) fn new(channels: [(AnyAdcChannel<'a, T>, SampleTime); N]) -> Self {
20 Self { 20 Self {
21 _channels: channels, 21 _channels: channels,
22 _phantom: PhantomData, 22 _phantom: PhantomData,
@@ -36,7 +36,7 @@ impl<T: Instance, const N: usize> InjectedAdc<T, N> {
36 } 36 }
37} 37}
38 38
39impl<T: Instance + AnyInstance, const N: usize> Drop for InjectedAdc<T, N> { 39impl<'a, T: Instance + AnyInstance, const N: usize> Drop for InjectedAdc<'a, T, N> {
40 fn drop(&mut self) { 40 fn drop(&mut self) {
41 T::stop(); 41 T::stop();
42 compiler_fence(Ordering::SeqCst); 42 compiler_fence(Ordering::SeqCst);
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index a55b99e6a..9040eefe5 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -25,7 +25,8 @@ use core::marker::PhantomData;
25#[allow(unused)] 25#[allow(unused)]
26#[cfg(not(any(adc_f3v3, adc_wba)))] 26#[cfg(not(any(adc_f3v3, adc_wba)))]
27pub use _version::*; 27pub use _version::*;
28use embassy_hal_internal::{PeripheralType, impl_peripheral}; 28#[allow(unused)]
29use embassy_hal_internal::PeripheralType;
29#[cfg(any(adc_f1, adc_f3v1, adc_v1, adc_l0, adc_f3v2))] 30#[cfg(any(adc_f1, adc_f3v1, adc_v1, adc_l0, adc_f3v2))]
30use embassy_sync::waitqueue::AtomicWaker; 31use embassy_sync::waitqueue::AtomicWaker;
31#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))] 32#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
@@ -241,10 +242,10 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
241 /// in order or require the sequence to have the same sample time for all channnels, depending 242 /// in order or require the sequence to have the same sample time for all channnels, depending
242 /// on the number and properties of the channels in the sequence. This method will panic if 243 /// on the number and properties of the channels in the sequence. This method will panic if
243 /// the hardware cannot deliver the requested configuration. 244 /// the hardware cannot deliver the requested configuration.
244 pub async fn read( 245 pub async fn read<'a, 'b: 'a>(
245 &mut self, 246 &mut self,
246 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>, 247 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>,
247 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, T::SampleTime)>, 248 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<'b, T>, T::SampleTime)>,
248 readings: &mut [u16], 249 readings: &mut [u16],
249 ) { 250 ) {
250 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); 251 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty");
@@ -313,11 +314,11 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
313 /// in order or require the sequence to have the same sample time for all channnels, depending 314 /// in order or require the sequence to have the same sample time for all channnels, depending
314 /// on the number and properties of the channels in the sequence. This method will panic if 315 /// on the number and properties of the channels in the sequence. This method will panic if
315 /// the hardware cannot deliver the requested configuration. 316 /// the hardware cannot deliver the requested configuration.
316 pub fn into_ring_buffered<'a>( 317 pub fn into_ring_buffered<'a, 'b>(
317 self, 318 self,
318 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>, 319 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>,
319 dma_buf: &'a mut [u16], 320 dma_buf: &'a mut [u16],
320 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, T::SampleTime)>, 321 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, T::SampleTime)>,
321 mode: RegularConversionMode, 322 mode: RegularConversionMode,
322 ) -> RingBufferedAdc<'a, T> { 323 ) -> RingBufferedAdc<'a, T> {
323 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 324 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
@@ -417,7 +418,10 @@ pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeri
417#[allow(private_bounds)] 418#[allow(private_bounds)]
418pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { 419pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
419 #[allow(unused_mut)] 420 #[allow(unused_mut)]
420 fn degrade_adc(mut self) -> AnyAdcChannel<T> { 421 fn degrade_adc<'a>(mut self) -> AnyAdcChannel<'a, T>
422 where
423 Self: 'a,
424 {
421 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))] 425 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))]
422 self.setup(); 426 self.setup();
423 427
@@ -433,14 +437,13 @@ pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
433/// 437///
434/// This is useful in scenarios where you need the ADC channels to have the same type, such as 438/// This is useful in scenarios where you need the ADC channels to have the same type, such as
435/// storing them in an array. 439/// storing them in an array.
436pub struct AnyAdcChannel<T> { 440pub struct AnyAdcChannel<'a, T> {
437 channel: u8, 441 channel: u8,
438 is_differential: bool, 442 is_differential: bool,
439 _phantom: PhantomData<T>, 443 _phantom: PhantomData<&'a mut T>,
440} 444}
441impl_peripheral!(AnyAdcChannel<T: AnyInstance>); 445impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<'_, T> {}
442impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<T> {} 446impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> {
443impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<T> {
444 fn channel(&self) -> u8 { 447 fn channel(&self) -> u8 {
445 self.channel 448 self.channel
446 } 449 }
@@ -450,7 +453,7 @@ impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<T> {
450 } 453 }
451} 454}
452 455
453impl<T> AnyAdcChannel<T> { 456impl<T> AnyAdcChannel<'_, T> {
454 #[allow(unused)] 457 #[allow(unused)]
455 pub fn get_hw_channel(&self) -> u8 { 458 pub fn get_hw_channel(&self) -> u8 {
456 self.channel 459 self.channel