diff options
| -rw-r--r-- | embassy-stm32/src/adc/g4.rs | 44 | ||||
| -rw-r--r-- | examples/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 @@ | |||
| 1 | use core::mem; | ||
| 2 | |||
| 1 | #[allow(unused)] | 3 | #[allow(unused)] |
| 2 | #[cfg(stm32h7)] | 4 | #[cfg(stm32h7)] |
| 3 | use pac::adc::vals::{Adcaldif, Difsel, Exten}; | 5 | use pac::adc::vals::{Adcaldif, Difsel, Exten}; |
| @@ -556,7 +558,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 556 | /// | 558 | /// |
| 557 | /// [`read`]: #method.read | 559 | /// [`read`]: #method.read |
| 558 | pub fn into_ring_buffered<'a>( | 560 | pub fn into_ring_buffered<'a>( |
| 559 | &mut self, | 561 | mut self, |
| 560 | dma: Peri<'a, impl RxDma<T>>, | 562 | dma: Peri<'a, impl RxDma<T>>, |
| 561 | dma_buf: &'a mut [u16], | 563 | dma_buf: &'a mut [u16], |
| 562 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | 564 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, |
| @@ -624,7 +626,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 624 | T::regs().cfgr().modify(|reg| { | 626 | T::regs().cfgr().modify(|reg| { |
| 625 | reg.set_cont(true); | 627 | reg.set_cont(true); |
| 626 | }); | 628 | }); |
| 627 | }, | 629 | } |
| 628 | RegularConversionMode::Triggered(trigger) => { | 630 | RegularConversionMode::Triggered(trigger) => { |
| 629 | T::regs().cfgr().modify(|r| { | 631 | T::regs().cfgr().modify(|r| { |
| 630 | r.set_cont(false); // New trigger is neede for each sample to be read | 632 | 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> { | |||
| 633 | } | 635 | } |
| 634 | } | 636 | } |
| 635 | 637 | ||
| 638 | mem::forget(self); | ||
| 639 | |||
| 636 | RingBufferedAdc::new(dma, dma_buf) | 640 | RingBufferedAdc::new(dma, dma_buf) |
| 637 | } | 641 | } |
| 638 | 642 | ||
| 639 | /// Configure a sequence of injected channels | 643 | /// Configure a sequence of injected channels |
| 640 | pub fn configure_injected_sequence<'a>( | 644 | pub fn configure_injected_sequence<'a>( |
| 641 | &mut self, | 645 | mut self, |
| 642 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | 646 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, |
| 643 | trigger: ConversionTrigger, | 647 | trigger: ConversionTrigger, |
| 644 | ) -> InjectedAdc<T> { | 648 | ) -> InjectedAdc<T> { |
| @@ -694,11 +698,14 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 694 | self.enable_injected_eos_interrupt(true); | 698 | self.enable_injected_eos_interrupt(true); |
| 695 | 699 | ||
| 696 | self.start_injected_conversion(); | 700 | self.start_injected_conversion(); |
| 701 | |||
| 702 | mem::forget(self); | ||
| 703 | |||
| 697 | InjectedAdc::new() | 704 | InjectedAdc::new() |
| 698 | } | 705 | } |
| 699 | 706 | ||
| 700 | pub fn into_regular_ringbuffered_and_injected_interrupts<'a>( | 707 | pub fn into_ring_buffered_and_injected<'a>( |
| 701 | &mut self, | 708 | self, |
| 702 | dma: Peri<'a, impl RxDma<T>>, | 709 | dma: Peri<'a, impl RxDma<T>>, |
| 703 | dma_buf: &'a mut [u16], | 710 | dma_buf: &'a mut [u16], |
| 704 | regular_sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | 711 | regular_sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, |
| @@ -706,18 +713,20 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 706 | injected_sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | 713 | injected_sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, |
| 707 | injected_trigger: ConversionTrigger, | 714 | injected_trigger: ConversionTrigger, |
| 708 | ) -> (RingBufferedAdc<'a, T>, InjectedAdc<T>) { | 715 | ) -> (RingBufferedAdc<'a, T>, InjectedAdc<T>) { |
| 709 | ( | 716 | unsafe { |
| 710 | self.into_ring_buffered( | 717 | ( |
| 711 | dma, | 718 | Self { |
| 712 | dma_buf, | 719 | adc: self.adc.clone_unchecked(), |
| 713 | regular_sequence, | 720 | sample_time: self.sample_time, |
| 714 | regular_conversion_mode, | 721 | } |
| 715 | ), | 722 | .into_ring_buffered(dma, dma_buf, regular_sequence, regular_conversion_mode), |
| 716 | self.configure_injected_sequence( | 723 | Self { |
| 717 | injected_sequence, | 724 | adc: self.adc.clone_unchecked(), |
| 718 | injected_trigger, | 725 | sample_time: self.sample_time, |
| 719 | ), | 726 | } |
| 720 | ) | 727 | .configure_injected_sequence(injected_sequence, injected_trigger), |
| 728 | ) | ||
| 729 | } | ||
| 721 | } | 730 | } |
| 722 | 731 | ||
| 723 | /// Start injected ADC conversion | 732 | /// Start injected ADC conversion |
| @@ -796,6 +805,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 796 | } | 805 | } |
| 797 | } | 806 | } |
| 798 | 807 | ||
| 808 | #[allow(dead_code)] | ||
| 799 | pub(super) fn stop_injected_conversions() { | 809 | pub(super) fn stop_injected_conversions() { |
| 800 | // Cancel injected conversions | 810 | // Cancel injected conversions |
| 801 | if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { | 811 | 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 @@ | |||
| 9 | use core::cell::RefCell; | 9 | use core::cell::RefCell; |
| 10 | 10 | ||
| 11 | use defmt::info; | 11 | use defmt::info; |
| 12 | use embassy_stm32::adc::{Adc, AdcChannel as _, Exten, SampleTime, ConversionTrigger, RegularConversionMode}; | 12 | use embassy_stm32::adc::InjectedAdc; |
| 13 | use embassy_stm32::adc::{Adc, AdcChannel as _, ConversionTrigger, Exten, RegularConversionMode, SampleTime}; | ||
| 13 | use embassy_stm32::interrupt::typelevel::{ADC1_2, Interrupt}; | 14 | use embassy_stm32::interrupt::typelevel::{ADC1_2, Interrupt}; |
| 14 | use embassy_stm32::peripherals::ADC1; | 15 | use embassy_stm32::peripherals::ADC1; |
| 15 | use embassy_stm32::time::Hertz; | 16 | use embassy_stm32::time::Hertz; |
| @@ -17,7 +18,6 @@ use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, Mms2}; | |||
| 17 | use embassy_stm32::timer::low_level::CountingMode; | 18 | use embassy_stm32::timer::low_level::CountingMode; |
| 18 | use embassy_stm32::{Config, interrupt}; | 19 | use embassy_stm32::{Config, interrupt}; |
| 19 | use embassy_sync::blocking_mutex::CriticalSectionMutex; | 20 | use embassy_sync::blocking_mutex::CriticalSectionMutex; |
| 20 | use embassy_stm32::adc::InjectedAdc; | ||
| 21 | use {critical_section, defmt_rtt as _, panic_probe as _}; | 21 | use {critical_section, defmt_rtt as _, panic_probe as _}; |
| 22 | 22 | ||
| 23 | static ADC1_HANDLE: CriticalSectionMutex<RefCell<Option<InjectedAdc<ADC1>>>> = | 23 | static ADC1_HANDLE: CriticalSectionMutex<RefCell<Option<InjectedAdc<ADC1>>>> = |
| @@ -76,7 +76,7 @@ async fn main(_spawner: embassy_executor::Spawner) { | |||
| 76 | pwm.set_mms2(Mms2::UPDATE); | 76 | pwm.set_mms2(Mms2::UPDATE); |
| 77 | 77 | ||
| 78 | // Configure regular conversions with DMA | 78 | // Configure regular conversions with DMA |
| 79 | let mut adc1 = Adc::new(p.ADC1); | 79 | let adc1 = Adc::new(p.ADC1); |
| 80 | 80 | ||
| 81 | let mut vrefint_channel = adc1.enable_vrefint().degrade_adc(); | 81 | let mut vrefint_channel = adc1.enable_vrefint().degrade_adc(); |
| 82 | let mut pa0 = p.PC1.degrade_adc(); | 82 | let mut pa0 = p.PC1.degrade_adc(); |
| @@ -95,10 +95,16 @@ async fn main(_spawner: embassy_executor::Spawner) { | |||
| 95 | // Using buffer of double size means the half-full interrupts will generate at the expected rate | 95 | // Using buffer of double size means the half-full interrupts will generate at the expected rate |
| 96 | let mut readings = [0u16; 4]; | 96 | let mut readings = [0u16; 4]; |
| 97 | 97 | ||
| 98 | let injected_trigger = ConversionTrigger { channel: ADC1_INJECTED_TRIGGER_TIM1_TRGO2, edge: Exten::RISING_EDGE }; | 98 | let injected_trigger = ConversionTrigger { |
| 99 | let regular_trigger = ConversionTrigger { channel: ADC1_REGULAR_TRIGGER_TIM1_TRGO2, edge: Exten::RISING_EDGE }; | 99 | channel: ADC1_INJECTED_TRIGGER_TIM1_TRGO2, |
| 100 | edge: Exten::RISING_EDGE, | ||
| 101 | }; | ||
| 102 | let regular_trigger = ConversionTrigger { | ||
| 103 | channel: ADC1_REGULAR_TRIGGER_TIM1_TRGO2, | ||
| 104 | edge: Exten::RISING_EDGE, | ||
| 105 | }; | ||
| 100 | 106 | ||
| 101 | let (mut ring_buffered_adc, injected_adc) = adc1.into_regular_ringbuffered_and_injected_interrupts( | 107 | let (mut ring_buffered_adc, injected_adc) = adc1.into_ring_buffered_and_injected( |
| 102 | dma1_ch1, | 108 | dma1_ch1, |
| 103 | &mut readings, | 109 | &mut readings, |
| 104 | regular_sequence, | 110 | regular_sequence, |
