From 338c5bfc96c2b575a3e4007c23359a49c85fae00 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 5 Nov 2025 14:15:25 -0600 Subject: consume regular ringbuf --- embassy-stm32/src/adc/g4.rs | 44 +++++++++++++--------- .../stm32g4/src/bin/adc_injected_and_regular.rs | 18 ++++++--- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index f60a14a72..5a36b0999 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs @@ -1,3 +1,5 @@ +use core::mem; + #[allow(unused)] #[cfg(stm32h7)] use pac::adc::vals::{Adcaldif, Difsel, Exten}; @@ -556,7 +558,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// /// [`read`]: #method.read pub fn into_ring_buffered<'a>( - &mut self, + mut self, dma: Peri<'a, impl RxDma>, dma_buf: &'a mut [u16], sequence: impl ExactSizeIterator, SampleTime)>, @@ -624,7 +626,7 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().cfgr().modify(|reg| { reg.set_cont(true); }); - }, + } RegularConversionMode::Triggered(trigger) => { T::regs().cfgr().modify(|r| { r.set_cont(false); // New trigger is neede for each sample to be read @@ -633,12 +635,14 @@ impl<'d, T: Instance> Adc<'d, T> { } } + mem::forget(self); + RingBufferedAdc::new(dma, dma_buf) } /// Configure a sequence of injected channels pub fn configure_injected_sequence<'a>( - &mut self, + mut self, sequence: impl ExactSizeIterator, SampleTime)>, trigger: ConversionTrigger, ) -> InjectedAdc { @@ -694,11 +698,14 @@ impl<'d, T: Instance> Adc<'d, T> { self.enable_injected_eos_interrupt(true); self.start_injected_conversion(); + + mem::forget(self); + InjectedAdc::new() } - pub fn into_regular_ringbuffered_and_injected_interrupts<'a>( - &mut self, + pub fn into_ring_buffered_and_injected<'a>( + self, dma: Peri<'a, impl RxDma>, dma_buf: &'a mut [u16], regular_sequence: impl ExactSizeIterator, SampleTime)>, @@ -706,18 +713,20 @@ impl<'d, T: Instance> Adc<'d, T> { injected_sequence: impl ExactSizeIterator, SampleTime)>, injected_trigger: ConversionTrigger, ) -> (RingBufferedAdc<'a, T>, InjectedAdc) { - ( - self.into_ring_buffered( - dma, - dma_buf, - regular_sequence, - regular_conversion_mode, - ), - self.configure_injected_sequence( - injected_sequence, - injected_trigger, - ), - ) + unsafe { + ( + Self { + adc: self.adc.clone_unchecked(), + sample_time: self.sample_time, + } + .into_ring_buffered(dma, dma_buf, regular_sequence, regular_conversion_mode), + Self { + adc: self.adc.clone_unchecked(), + sample_time: self.sample_time, + } + .configure_injected_sequence(injected_sequence, injected_trigger), + ) + } } /// Start injected ADC conversion @@ -796,6 +805,7 @@ impl<'d, T: Instance> Adc<'d, T> { } } + #[allow(dead_code)] pub(super) fn stop_injected_conversions() { // Cancel injected conversions if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { diff --git a/examples/stm32g4/src/bin/adc_injected_and_regular.rs b/examples/stm32g4/src/bin/adc_injected_and_regular.rs index 85e01dbf3..d0c577b4b 100644 --- a/examples/stm32g4/src/bin/adc_injected_and_regular.rs +++ b/examples/stm32g4/src/bin/adc_injected_and_regular.rs @@ -9,7 +9,8 @@ use core::cell::RefCell; use defmt::info; -use embassy_stm32::adc::{Adc, AdcChannel as _, Exten, SampleTime, ConversionTrigger, RegularConversionMode}; +use embassy_stm32::adc::InjectedAdc; +use embassy_stm32::adc::{Adc, AdcChannel as _, ConversionTrigger, Exten, RegularConversionMode, SampleTime}; use embassy_stm32::interrupt::typelevel::{ADC1_2, Interrupt}; use embassy_stm32::peripherals::ADC1; use embassy_stm32::time::Hertz; @@ -17,7 +18,6 @@ use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, Mms2}; use embassy_stm32::timer::low_level::CountingMode; use embassy_stm32::{Config, interrupt}; use embassy_sync::blocking_mutex::CriticalSectionMutex; -use embassy_stm32::adc::InjectedAdc; use {critical_section, defmt_rtt as _, panic_probe as _}; static ADC1_HANDLE: CriticalSectionMutex>>> = @@ -76,7 +76,7 @@ async fn main(_spawner: embassy_executor::Spawner) { pwm.set_mms2(Mms2::UPDATE); // Configure regular conversions with DMA - let mut adc1 = Adc::new(p.ADC1); + let adc1 = Adc::new(p.ADC1); let mut vrefint_channel = adc1.enable_vrefint().degrade_adc(); let mut pa0 = p.PC1.degrade_adc(); @@ -95,10 +95,16 @@ async fn main(_spawner: embassy_executor::Spawner) { // Using buffer of double size means the half-full interrupts will generate at the expected rate let mut readings = [0u16; 4]; - let injected_trigger = ConversionTrigger { channel: ADC1_INJECTED_TRIGGER_TIM1_TRGO2, edge: Exten::RISING_EDGE }; - let regular_trigger = ConversionTrigger { channel: ADC1_REGULAR_TRIGGER_TIM1_TRGO2, edge: Exten::RISING_EDGE }; + let injected_trigger = ConversionTrigger { + channel: ADC1_INJECTED_TRIGGER_TIM1_TRGO2, + edge: Exten::RISING_EDGE, + }; + let regular_trigger = ConversionTrigger { + channel: ADC1_REGULAR_TRIGGER_TIM1_TRGO2, + edge: Exten::RISING_EDGE, + }; - let (mut ring_buffered_adc, injected_adc) = adc1.into_regular_ringbuffered_and_injected_interrupts( + let (mut ring_buffered_adc, injected_adc) = adc1.into_ring_buffered_and_injected( dma1_ch1, &mut readings, regular_sequence, -- cgit