From e32f78fde6f8130f1eb3effa131e42b7ca153ba6 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 12 Nov 2025 13:14:15 -0600 Subject: stm32/adc: extract into common add common low-level interface for adc --- examples/stm32f4/src/bin/adc.rs | 2 +- examples/stm32f4/src/bin/adc_dma.rs | 8 +++++--- examples/stm32g0/src/bin/adc_oversampling.rs | 14 ++++++++------ examples/stm32g4/src/bin/adc.rs | 4 ++-- examples/stm32g4/src/bin/adc_differential.rs | 2 +- examples/stm32g4/src/bin/adc_dma.rs | 2 +- examples/stm32g4/src/bin/adc_injected_and_regular.rs | 2 +- examples/stm32g4/src/bin/adc_oversampling.rs | 13 ++++++++----- examples/stm32l4/src/bin/adc.rs | 9 ++++++--- examples/stm32l4/src/bin/adc_dma.rs | 5 +++-- examples/stm32u0/src/bin/adc.rs | 7 ++++--- examples/stm32u5/src/bin/adc.rs | 16 +++++++++------- 12 files changed, 49 insertions(+), 35 deletions(-) (limited to 'examples') diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs index 5628cb827..694e85657 100644 --- a/examples/stm32f4/src/bin/adc.rs +++ b/examples/stm32f4/src/bin/adc.rs @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut delay = Delay; - let mut adc = Adc::new(p.ADC1); + let mut adc = Adc::new_with_config(p.ADC1, Default::default()); let mut pin = p.PC1; let mut vrefint = adc.enable_vrefint(); diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs index 01b881c79..d61b1b2eb 100644 --- a/examples/stm32f4/src/bin/adc_dma.rs +++ b/examples/stm32f4/src/bin/adc_dma.rs @@ -4,7 +4,7 @@ use cortex_m::singleton; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::Peripherals; -use embassy_stm32::adc::{Adc, AdcChannel, RingBufferedAdc, SampleTime}; +use embassy_stm32::adc::{Adc, AdcChannel, RegularConversionMode, RingBufferedAdc, SampleTime}; use embassy_time::Instant; use {defmt_rtt as _, panic_probe as _}; @@ -20,8 +20,8 @@ async fn adc_task(p: Peripherals) { let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); - let adc = Adc::new(p.ADC1); - let adc2 = Adc::new(p.ADC2); + let adc = Adc::new_with_config(p.ADC1, Default::default()); + let adc2 = Adc::new_with_config(p.ADC2, Default::default()); let mut adc: RingBufferedAdc = adc.into_ring_buffered( p.DMA2_CH0, @@ -31,6 +31,7 @@ async fn adc_task(p: Peripherals) { (p.PA2.degrade_adc(), SampleTime::CYCLES112), ] .into_iter(), + RegularConversionMode::Continuous, ); let mut adc2: RingBufferedAdc = adc2.into_ring_buffered( p.DMA2_CH2, @@ -40,6 +41,7 @@ async fn adc_task(p: Peripherals) { (p.PA3.degrade_adc(), SampleTime::CYCLES112), ] .into_iter(), + RegularConversionMode::Continuous, ); // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around diff --git a/examples/stm32g0/src/bin/adc_oversampling.rs b/examples/stm32g0/src/bin/adc_oversampling.rs index f6979889d..aa8b1771b 100644 --- a/examples/stm32g0/src/bin/adc_oversampling.rs +++ b/examples/stm32g0/src/bin/adc_oversampling.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::adc::{Adc, Clock, Ovsr, Ovss, Presc, SampleTime}; +use embassy_stm32::adc::{Adc, AdcConfig, Clock, Ovsr, Ovss, Presc, SampleTime}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -16,12 +16,14 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Adc oversample test"); - let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 }); - let mut pin = p.PA1; + let mut config = AdcConfig::default(); + config.clock = Some(Clock::Async { div: Presc::DIV1 }); + config.oversampling_ratio = Some(Ovsr::MUL16); + config.oversampling_shift = Some(Ovss::NO_SHIFT); + config.oversampling_enable = Some(true); - adc.set_oversampling_ratio(Ovsr::MUL16); - adc.set_oversampling_shift(Ovss::NO_SHIFT); - adc.oversampling_enable(true); + let mut adc = Adc::new_with_config(p.ADC1, config); + let mut pin = p.PA1; loop { let v = adc.blocking_read(&mut pin, SampleTime::CYCLES1_5); diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index 94315141c..2149e0748 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -28,9 +28,9 @@ async fn main(_spawner: Spawner) { let mut p = embassy_stm32::init(config); info!("Hello World!"); - let mut adc = Adc::new(p.ADC2); + let mut adc = Adc::new(p.ADC2, Default::default()); - let mut adc_temp = Adc::new(p.ADC1); + let mut adc_temp = Adc::new(p.ADC1, Default::default()); let mut temperature = adc_temp.enable_temperature(); loop { diff --git a/examples/stm32g4/src/bin/adc_differential.rs b/examples/stm32g4/src/bin/adc_differential.rs index 2773723e9..6dedf88d6 100644 --- a/examples/stm32g4/src/bin/adc_differential.rs +++ b/examples/stm32g4/src/bin/adc_differential.rs @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) { } let p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1); + let mut adc = Adc::new(p.ADC1, Default::default()); let mut differential_channel = (p.PA0, p.PA1); // can also use diff --git a/examples/stm32g4/src/bin/adc_dma.rs b/examples/stm32g4/src/bin/adc_dma.rs index ef8b0c3c2..478b6b2ca 100644 --- a/examples/stm32g4/src/bin/adc_dma.rs +++ b/examples/stm32g4/src/bin/adc_dma.rs @@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); - let mut adc = Adc::new(p.ADC1); + let mut adc = Adc::new(p.ADC1, Default::default()); let mut dma = p.DMA1_CH1; let mut vrefint_channel = adc.enable_vrefint().degrade_adc(); diff --git a/examples/stm32g4/src/bin/adc_injected_and_regular.rs b/examples/stm32g4/src/bin/adc_injected_and_regular.rs index 3ae2ff064..1e97fa925 100644 --- a/examples/stm32g4/src/bin/adc_injected_and_regular.rs +++ b/examples/stm32g4/src/bin/adc_injected_and_regular.rs @@ -77,7 +77,7 @@ async fn main(_spawner: embassy_executor::Spawner) { pwm.set_mms2(Mms2::UPDATE); // Configure regular conversions with DMA - let adc1 = Adc::new(p.ADC1); + let adc1 = Adc::new(p.ADC1, Default::default()); let vrefint_channel = adc1.enable_vrefint().degrade_adc(); let pa0 = p.PC1.degrade_adc(); diff --git a/examples/stm32g4/src/bin/adc_oversampling.rs b/examples/stm32g4/src/bin/adc_oversampling.rs index cb99ab2a7..87ffea4be 100644 --- a/examples/stm32g4/src/bin/adc_oversampling.rs +++ b/examples/stm32g4/src/bin/adc_oversampling.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::Config; use embassy_stm32::adc::vals::{Rovsm, Trovs}; -use embassy_stm32::adc::{Adc, SampleTime}; +use embassy_stm32::adc::{Adc, AdcConfig, SampleTime}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -32,7 +32,8 @@ async fn main(_spawner: Spawner) { } let mut p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1); + let mut config = AdcConfig::default(); + // From https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf // page652 Oversampler // Table 172. Maximum output results vs N and M. Grayed values indicates truncation @@ -44,9 +45,11 @@ async fn main(_spawner: Spawner) { // 0x05 oversampling ratio X64 // 0x06 oversampling ratio X128 // 0x07 oversampling ratio X256 - adc.set_oversampling_ratio(0x03); // ratio X3 - adc.set_oversampling_shift(0b0000); // no shift - adc.enable_regular_oversampling_mode(Rovsm::RESUMED, Trovs::AUTOMATIC, true); + config.oversampling_ratio = Some(0x03); // ratio X3 + config.oversampling_shift = Some(0b0000); // no shift + config.oversampling_mode = Some((Rovsm::RESUMED, Trovs::AUTOMATIC, true)); + + let mut adc = Adc::new(p.ADC1, config); loop { let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES6_5); diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index 835bf5411..42766a5e3 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -3,7 +3,7 @@ use defmt::*; use embassy_stm32::Config; -use embassy_stm32::adc::{Adc, Resolution, SampleTime}; +use embassy_stm32::adc::{Adc, AdcConfig, Resolution, SampleTime}; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] @@ -17,9 +17,12 @@ fn main() -> ! { } let p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1); + let mut config = AdcConfig::default(); + config.resolution = Some(Resolution::BITS8); + + let mut adc = Adc::new_with_config(p.ADC1, config); //adc.enable_vref(); - adc.set_resolution(Resolution::BITS8); + let mut channel = p.PC0; loop { diff --git a/examples/stm32l4/src/bin/adc_dma.rs b/examples/stm32l4/src/bin/adc_dma.rs index ab1e9d2e9..550da95a4 100644 --- a/examples/stm32l4/src/bin/adc_dma.rs +++ b/examples/stm32l4/src/bin/adc_dma.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::Config; -use embassy_stm32::adc::{Adc, AdcChannel, SampleTime}; +use embassy_stm32::adc::{Adc, AdcChannel, RegularConversionMode, SampleTime}; use {defmt_rtt as _, panic_probe as _}; const DMA_BUF_LEN: usize = 512; @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { } let p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1); + let adc = Adc::new(p.ADC1); let adc_pin0 = p.PA0.degrade_adc(); let adc_pin1 = p.PA1.degrade_adc(); let mut adc_dma_buf = [0u16; DMA_BUF_LEN]; @@ -29,6 +29,7 @@ async fn main(_spawner: Spawner) { p.DMA1_CH1, &mut adc_dma_buf, [(adc_pin0, SampleTime::CYCLES640_5), (adc_pin1, SampleTime::CYCLES640_5)].into_iter(), + RegularConversionMode::Continuous, ); info!("starting measurement loop"); diff --git a/examples/stm32u0/src/bin/adc.rs b/examples/stm32u0/src/bin/adc.rs index 4fbc6f17f..53bd37303 100644 --- a/examples/stm32u0/src/bin/adc.rs +++ b/examples/stm32u0/src/bin/adc.rs @@ -3,7 +3,7 @@ use defmt::*; use embassy_stm32::Config; -use embassy_stm32::adc::{Adc, Resolution, SampleTime}; +use embassy_stm32::adc::{Adc, AdcConfig, Resolution, SampleTime}; use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; @@ -18,8 +18,9 @@ fn main() -> ! { } let p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1); - adc.set_resolution(Resolution::BITS8); + let mut config = AdcConfig::default(); + config.resolution = Some(Resolution::BITS8); + let mut adc = Adc::new_with_config(p.ADC1, config); let mut channel = p.PC0; loop { diff --git a/examples/stm32u5/src/bin/adc.rs b/examples/stm32u5/src/bin/adc.rs index 99944f7c7..6b9a91d6e 100644 --- a/examples/stm32u5/src/bin/adc.rs +++ b/examples/stm32u5/src/bin/adc.rs @@ -2,7 +2,7 @@ #![no_main] use defmt::*; -use embassy_stm32::adc::{self, AdcChannel, SampleTime, adc4}; +use embassy_stm32::adc::{self, AdcChannel, AdcConfig, SampleTime, adc4}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -12,19 +12,21 @@ async fn main(_spawner: embassy_executor::Spawner) { let mut p = embassy_stm32::init(config); // **** ADC1 init **** - let mut adc1 = adc::Adc::new(p.ADC1); + let mut config = AdcConfig::default(); + config.averaging = Some(adc::Averaging::Samples1024); + config.resolution = Some(adc::Resolution::BITS14); + let mut adc1 = adc::Adc::new_with_config(p.ADC1, config); let mut adc1_pin1 = p.PA3; // A0 on nucleo u5a5 let mut adc1_pin2 = p.PA2; // A1 - adc1.set_resolution(adc::Resolution::BITS14); - adc1.set_averaging(adc::Averaging::Samples1024); let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14); // **** ADC2 init **** - let mut adc2 = adc::Adc::new(p.ADC2); + let mut config = AdcConfig::default(); + config.averaging = Some(adc::Averaging::Samples1024); + config.resolution = Some(adc::Resolution::BITS14); + let mut adc2 = adc::Adc::new_with_config(p.ADC2, config); let mut adc2_pin1 = p.PC3; // A2 let mut adc2_pin2 = p.PB0; // A3 - adc2.set_resolution(adc::Resolution::BITS14); - adc2.set_averaging(adc::Averaging::Samples1024); let max2 = adc::resolution_to_max_count(adc::Resolution::BITS14); // **** ADC4 init **** -- cgit