aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-21 21:30:24 +0000
committerGitHub <[email protected]>2025-11-21 21:30:24 +0000
commitbbbeb6cea5551afdc21274101ffb4194c81b0987 (patch)
tree84b0509869731a69b38178fbf4d632e96f28da13
parent96a026c73bad2ebb8dfc78e88c9690611bf2cb97 (diff)
parent14436ce1300a5d621b617d56ee037e09ce55ea0a (diff)
Merge pull request #4928 from xoviat/adc
adc: fix start sequence for blocking_read
-rw-r--r--embassy-stm32/src/adc/adc4.rs35
-rw-r--r--embassy-stm32/src/adc/mod.rs2
-rw-r--r--embassy-stm32/src/adc/v2.rs17
-rw-r--r--tests/stm32/Cargo.toml8
-rw-r--r--tests/stm32/src/bin/adc.rs39
-rw-r--r--tests/stm32/src/common.rs1
6 files changed, 70 insertions, 32 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!(
113 } 113 }
114 114
115 fn enable() { 115 fn enable() {
116 let cr_initial = ADC4::regs().cr().read(); 116 if !ADC4::regs().cr().read().aden() || !ADC4::regs().isr().read().adrdy() {
117 let isr_initial = ADC4::regs().isr().read(); 117 ADC4::regs().isr().write(|w| w.set_adrdy(true));
118 118 ADC4::regs().cr().modify(|w| w.set_aden(true));
119 if cr_initial.aden() && isr_initial.adrdy() { 119 while !ADC4::regs().isr().read().adrdy() {}
120 return;
121 }
122
123 if cr_initial.aden() || cr_initial.adstart() {
124 if cr_initial.adstart() {
125 ADC4::regs().cr().modify(|w| w.set_adstp(true));
126 while ADC4::regs().cr().read().adstart() {}
127 }
128
129 ADC4::regs().cr().modify(|w| w.set_addis(true));
130 while ADC4::regs().cr().read().aden() {}
131 } 120 }
132
133 ADC4::regs().isr().write(|w| w.set_adrdy(true));
134 ADC4::regs().cr().modify(|w| w.set_aden(true));
135 while !ADC4::regs().isr().read().adrdy() {}
136 } 121 }
137 122
138 fn start() { 123 fn start() {
@@ -143,13 +128,17 @@ foreach_adc!(
143 } 128 }
144 129
145 fn stop() { 130 fn stop() {
146 if ADC4::regs().cr().read().adstart() && !ADC4::regs().cr().read().addis() { 131 let cr = ADC4::regs().cr().read();
147 ADC4::regs().cr().modify(|reg| { 132 if cr.adstart() {
148 reg.set_adstp(true); 133 ADC4::regs().cr().modify(|w| w.set_adstp(true));
149 });
150 while ADC4::regs().cr().read().adstart() {} 134 while ADC4::regs().cr().read().adstart() {}
151 } 135 }
152 136
137 if cr.aden() || cr.adstart() {
138 ADC4::regs().cr().modify(|w| w.set_addis(true));
139 while ADC4::regs().cr().read().aden() {}
140 }
141
153 // Reset configuration. 142 // Reset configuration.
154 ADC4::regs().cfgr1().modify(|reg| { 143 ADC4::regs().cfgr1().modify(|reg| {
155 reg.set_dmaen(false); 144 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> {
192 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))] 192 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))]
193 channel.setup(); 193 channel.setup();
194 194
195 // Ensure no conversions are ongoing
196 T::stop();
195 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))] 197 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))]
196 T::enable(); 198 T::enable();
197 T::configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter()); 199 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<T: Instance> super::SealedAnyInstance for T {
79 T::regs().dr().as_ptr() as *mut u16 79 T::regs().dr().as_ptr() as *mut u16
80 } 80 }
81 81
82 fn enable() {} 82 fn enable() {
83 T::regs().cr2().modify(|reg| {
84 reg.set_adon(true);
85 });
86
87 blocking_delay_us(3);
88 }
83 89
84 fn start() { 90 fn start() {
85 // Begin ADC conversions 91 // Begin ADC conversions
86 T::regs().cr2().modify(|reg| { 92 T::regs().cr2().modify(|reg| {
87 reg.set_adon(true);
88 reg.set_swstart(true); 93 reg.set_swstart(true);
89 }); 94 });
90 } 95 }
@@ -198,7 +203,7 @@ impl<T: Instance> super::SealedAnyInstance for T {
198 203
199impl<'d, T> Adc<'d, T> 204impl<'d, T> Adc<'d, T>
200where 205where
201 T: Instance, 206 T: Instance + super::AnyInstance,
202{ 207{
203 pub fn new(adc: Peri<'d, T>) -> Self { 208 pub fn new(adc: Peri<'d, T>) -> Self {
204 Self::new_with_config(adc, Default::default()) 209 Self::new_with_config(adc, Default::default())
@@ -209,11 +214,7 @@ where
209 214
210 let presc = from_pclk2(T::frequency()); 215 let presc = from_pclk2(T::frequency());
211 T::common_regs().ccr().modify(|w| w.set_adcpre(presc)); 216 T::common_regs().ccr().modify(|w| w.set_adcpre(presc));
212 T::regs().cr2().modify(|reg| { 217 T::enable();
213 reg.set_adon(true);
214 });
215
216 blocking_delay_us(3);
217 218
218 if let Some(resolution) = config.resolution { 219 if let Some(resolution) = config.resolution {
219 T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); 220 T::regs().cr1().modify(|reg| reg.set_res(resolution.into()));
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
32stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"] 32stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"]
33stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash 33stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash
34stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng", "hsem", "stop"] 34stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng", "hsem", "stop"]
35stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"] 35stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash", "adc"]
36stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono", "hsem"] 36stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono", "hsem"]
37stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] 37stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
38stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] 38stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"]
@@ -56,6 +56,7 @@ mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"]
56embassy-stm32-wpan = [] 56embassy-stm32-wpan = []
57not-gpdma = [] 57not-gpdma = []
58dac = [] 58dac = []
59adc = []
59ucpd = [] 60ucpd = []
60cordic = ["dep:num-traits"] 61cordic = ["dep:num-traits"]
61hsem = [] 62hsem = []
@@ -111,6 +112,11 @@ path = "src/bin/afio.rs"
111required-features = [ "afio",] 112required-features = [ "afio",]
112 113
113[[bin]] 114[[bin]]
115name = "adc"
116path = "src/bin/adc.rs"
117required-features = [ "adc",]
118
119[[bin]]
114name = "can" 120name = "can"
115path = "src/bin/can.rs" 121path = "src/bin/can.rs"
116required-features = [ "can",] 122required-features = [ "can",]
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 @@
1#![no_std]
2#![no_main]
3
4// required-features: dac
5
6#[path = "../common.rs"]
7mod common;
8
9use common::*;
10use embassy_executor::Spawner;
11use embassy_stm32::adc::{Adc, SampleTime};
12use embassy_time::Timer;
13use {defmt_rtt as _, panic_probe as _};
14
15#[embassy_executor::main]
16async fn main(_spawner: Spawner) {
17 // Initialize the board and obtain a Peripherals instance
18 let p: embassy_stm32::Peripherals = init();
19
20 let adc = peri!(p, ADC);
21 let mut adc_pin = peri!(p, DAC_PIN);
22
23 let mut adc = Adc::new_adc4(adc);
24
25 // Now wait a little to obtain a stable value
26 Timer::after_millis(30).await;
27 let _ = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0));
28
29 for _ in 0..=255 {
30 // Now wait a little to obtain a stable value
31 Timer::after_millis(30).await;
32
33 // Need to steal the peripherals here because PA4 is obviously in use already
34 let _ = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0));
35 }
36
37 info!("Test OK");
38 cortex_m::asm::bkpt();
39}
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!(
259define_peris!( 259define_peris!(
260 UART = LPUART1, UART_TX = PB5, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, 260 UART = LPUART1, UART_TX = PB5, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1,
261 SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, 261 SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1,
262 ADC = ADC4, DAC_PIN = PA0,
262 @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, 263 @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;},
263); 264);
264#[cfg(feature = "stm32h7s3l8")] 265#[cfg(feature = "stm32h7s3l8")]