From 1cc2643ae60d429d0389213f5c1f6bbc007c6a2b Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 21 Nov 2025 07:43:37 -0600 Subject: adc: fix start sequence for blocking_read --- embassy-stm32/src/adc/adc4.rs | 35 ++++++++++++----------------------- embassy-stm32/src/adc/mod.rs | 2 ++ embassy-stm32/src/adc/v2.rs | 17 +++++++++-------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs index 472eb46fd..453513309 100644 --- a/embassy-stm32/src/adc/adc4.rs +++ b/embassy-stm32/src/adc/adc4.rs @@ -113,26 +113,11 @@ foreach_adc!( } fn enable() { - let cr_initial = ADC4::regs().cr().read(); - let isr_initial = ADC4::regs().isr().read(); - - if cr_initial.aden() && isr_initial.adrdy() { - return; - } - - if cr_initial.aden() || cr_initial.adstart() { - if cr_initial.adstart() { - ADC4::regs().cr().modify(|w| w.set_adstp(true)); - while ADC4::regs().cr().read().adstart() {} - } - - ADC4::regs().cr().modify(|w| w.set_addis(true)); - while ADC4::regs().cr().read().aden() {} + if !ADC4::regs().cr().read().aden() || !ADC4::regs().isr().read().adrdy() { + ADC4::regs().isr().write(|w| w.set_adrdy(true)); + ADC4::regs().cr().modify(|w| w.set_aden(true)); + while !ADC4::regs().isr().read().adrdy() {} } - - ADC4::regs().isr().write(|w| w.set_adrdy(true)); - ADC4::regs().cr().modify(|w| w.set_aden(true)); - while !ADC4::regs().isr().read().adrdy() {} } fn start() { @@ -143,13 +128,17 @@ foreach_adc!( } fn stop() { - if ADC4::regs().cr().read().adstart() && !ADC4::regs().cr().read().addis() { - ADC4::regs().cr().modify(|reg| { - reg.set_adstp(true); - }); + let cr = ADC4::regs().cr().read(); + if cr.adstart() { + ADC4::regs().cr().modify(|w| w.set_adstp(true)); while ADC4::regs().cr().read().adstart() {} } + if cr.aden() || cr.adstart() { + ADC4::regs().cr().modify(|w| w.set_addis(true)); + while ADC4::regs().cr().read().aden() {} + } + // Reset configuration. ADC4::regs().cfgr1().modify(|reg| { reg.set_dmaen(false); diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 755cb78c2..6d53d9b91 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -192,6 +192,8 @@ impl<'d, T: AnyInstance> Adc<'d, T> { #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))] channel.setup(); + // Ensure no conversions are ongoing + T::stop(); #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))] T::enable(); T::configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter()); diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 341b15674..3c4431ae0 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -79,12 +79,17 @@ impl super::SealedAnyInstance for T { T::regs().dr().as_ptr() as *mut u16 } - fn enable() {} + fn enable() { + T::regs().cr2().modify(|reg| { + reg.set_adon(true); + }); + + blocking_delay_us(3); + } fn start() { // Begin ADC conversions T::regs().cr2().modify(|reg| { - reg.set_adon(true); reg.set_swstart(true); }); } @@ -198,7 +203,7 @@ impl super::SealedAnyInstance for T { impl<'d, T> Adc<'d, T> where - T: Instance, + T: Instance + super::AnyInstance, { pub fn new(adc: Peri<'d, T>) -> Self { Self::new_with_config(adc, Default::default()) @@ -209,11 +214,7 @@ where let presc = from_pclk2(T::frequency()); T::common_regs().ccr().modify(|w| w.set_adcpre(presc)); - T::regs().cr2().modify(|reg| { - reg.set_adon(true); - }); - - blocking_delay_us(3); + T::enable(); if let Some(resolution) = config.resolution { T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); -- cgit From 14436ce1300a5d621b617d56ee037e09ce55ea0a Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 21 Nov 2025 08:22:31 -0600 Subject: adc: add test for wba --- tests/stm32/Cargo.toml | 8 +++++++- tests/stm32/src/bin/adc.rs | 39 +++++++++++++++++++++++++++++++++++++++ tests/stm32/src/common.rs | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/stm32/src/bin/adc.rs diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 8fcb6b2b4..496a9de18 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -32,7 +32,7 @@ stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash", "dual-ba stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"] stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng", "hsem", "stop"] -stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"] +stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash", "adc"] stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono", "hsem"] stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] @@ -56,6 +56,7 @@ mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] embassy-stm32-wpan = [] not-gpdma = [] dac = [] +adc = [] ucpd = [] cordic = ["dep:num-traits"] hsem = [] @@ -110,6 +111,11 @@ name = "afio" path = "src/bin/afio.rs" required-features = [ "afio",] +[[bin]] +name = "adc" +path = "src/bin/adc.rs" +required-features = [ "adc",] + [[bin]] name = "can" path = "src/bin/can.rs" diff --git a/tests/stm32/src/bin/adc.rs b/tests/stm32/src/bin/adc.rs new file mode 100644 index 000000000..6cedc6498 --- /dev/null +++ b/tests/stm32/src/bin/adc.rs @@ -0,0 +1,39 @@ +#![no_std] +#![no_main] + +// required-features: dac + +#[path = "../common.rs"] +mod common; + +use common::*; +use embassy_executor::Spawner; +use embassy_stm32::adc::{Adc, SampleTime}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + // Initialize the board and obtain a Peripherals instance + let p: embassy_stm32::Peripherals = init(); + + let adc = peri!(p, ADC); + let mut adc_pin = peri!(p, DAC_PIN); + + let mut adc = Adc::new_adc4(adc); + + // Now wait a little to obtain a stable value + Timer::after_millis(30).await; + let _ = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0)); + + for _ in 0..=255 { + // Now wait a little to obtain a stable value + Timer::after_millis(30).await; + + // Need to steal the peripherals here because PA4 is obviously in use already + let _ = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0)); + } + + info!("Test OK"); + cortex_m::asm::bkpt(); +} diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 096cce947..9f88b182a 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -259,6 +259,7 @@ define_peris!( define_peris!( UART = LPUART1, UART_TX = PB5, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + ADC = ADC4, DAC_PIN = PA0, @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, ); #[cfg(feature = "stm32h7s3l8")] -- cgit