diff options
| -rw-r--r-- | embassy-stm32/src/adc/g4.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/injected.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 27 |
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 | ||
| 534 | impl<T: Instance, const N: usize> InjectedAdc<T, N> { | 534 | impl<'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; | |||
| 10 | use crate::adc::{Adc, AnyInstance}; | 10 | use crate::adc::{Adc, AnyInstance}; |
| 11 | 11 | ||
| 12 | /// Injected ADC sequence with owned channels. | 12 | /// Injected ADC sequence with owned channels. |
| 13 | pub struct InjectedAdc<T: Instance, const N: usize> { | 13 | pub 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 | ||
| 18 | impl<T: Instance, const N: usize> InjectedAdc<T, N> { | 18 | impl<'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 | ||
| 39 | impl<T: Instance + AnyInstance, const N: usize> Drop for InjectedAdc<T, N> { | 39 | impl<'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)))] |
| 27 | pub use _version::*; | 27 | pub use _version::*; |
| 28 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; | 28 | #[allow(unused)] |
| 29 | use 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))] |
| 30 | use embassy_sync::waitqueue::AtomicWaker; | 31 | use 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)] |
| 418 | pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { | 419 | pub 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. |
| 436 | pub struct AnyAdcChannel<T> { | 440 | pub 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 | } |
| 441 | impl_peripheral!(AnyAdcChannel<T: AnyInstance>); | 445 | impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<'_, T> {} |
| 442 | impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<T> {} | 446 | impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> { |
| 443 | impl<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 | ||
| 453 | impl<T> AnyAdcChannel<T> { | 456 | impl<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 |
