Open katyo opened 1 year ago
I run into the same problem but actually only if I use the crates. If I use the dependencies from path it works fine for me. Did you fix it for you?
Same issue here on a stm32f103c6
(Infinite wait on adc.read()
).
I run into the same problem but actually only if I use the crates. If I use the dependencies from path it works fine for me. Did you fix it for you?
Using the suggested method with 3638df789e4f498b9058bbeb27bdddab4a80bd49 I can read the adc value one time for each ADC.
On the second invocation it hangs again.
The output of the ADC-example for stm32f1
is:
0.000000 TRACE BDCR ok: 00008200
└─ embassy_stm32::rcc::bd::{impl#2}::init @ /home/paulz/src/embedded/embassy/embassy-stm32/src/fmt.rs:117
0.000000 DEBUG rcc: Clocks { hclk1: Some(Hertz(8000000)), pclk1: Some(Hertz(8000000)), pclk1_tim: Some(Hertz(8000000)), pclk2: Some(Hertz(8000000)), pclk2_tim: Some(Hertz(8000000)), rtc: Some(Hertz(40000)), sys: Some(Hertz(8000000)), usb: None }
└─ embassy_stm32::rcc::set_freqs @ /home/paulz/src/embedded/embassy/embassy-stm32/src/fmt.rs:130
0.000030 INFO Hello World!
└─ embassy_stm32f1_examples::____embassy_main_task::{async_fn#0} @ src/main.rs:19
The code hangs on the first loop iteration because read
got called for vref
.
The issue seems to be timing related.
Adding a Timer::after_ticks(1).await;
to https://github.com/embassy-rs/embassy/blob/3638df789e4f498b9058bbeb27bdddab4a80bd49/embassy-stm32/src/adc/f1.rs#L126 fixed the issue xD
Edit: even a Timer::after_ticks(1).await;
in L124 fixes the issue.
Just spent the evening getting stuck on the same thing. Turns out, for me it was some compiler flags. If I remove the config below, the ADC works.
[profile.dev] lto = true opt-level = 1 //doesnt matter what level, won't work.
ADC example functions when built without the release profile, or if opt-level = 0
.
Actually this looks like it's caused entirely by the #3166. The interrupt simply does not get unmasked in the NVIC. I can get the example to run correctly with the patch on release builds:
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs
index 541ff159e..417730a4a 100644
--- a/examples/stm32f1/src/bin/adc.rs
+++ b/examples/stm32f1/src/bin/adc.rs
@@ -4,6 +4,8 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::adc::Adc;
+use embassy_stm32::interrupt;
+use embassy_stm32::interrupt::InterruptExt;
use embassy_stm32::peripherals::ADC1;
use embassy_stm32::{adc, bind_interrupts};
use embassy_time::Timer;
@@ -22,6 +24,11 @@ async fn main(_spawner: Spawner) {
let mut pin = p.PB1;
let mut vrefint = adc.enable_vref();
+
+ unsafe {
+ interrupt::ADC1_2.enable();
+ }
+
let vrefint_sample = adc.read(&mut vrefint).await;
let convert_to_millivolts = |sample| {
// From http://www.st.com/resource/en/datasheet/CD00161566.pdf
If I drop the interrupt::ADC1_2.enable()
I observe the expected hang, since no ADC1_2
handler actually gets called.
I have no clue why this code sometimes works on debug builds more often than on release ones.
Sorry, I'm not at all familiar with the code base so my thinking can be waaay off. But my guess is that the poll from .convert
gets called since some other interrupt has occured in the meantime? Looks like that's why Timer::after_ticks(1).await
helps in this case - it polls the task and the EOC
flag is already set, so the Poll
is ready:
if !T::regs().cr2().read().swstart() && T::regs().sr().read().eoc() {
Poll::Ready(())
} else {
This should be an easy fix in the driver either way by actually unmasking the EOC interrupt like all other ADC drivers do. P.S. I'll work on the fix and upstreaming it. Should be trivial
I run ADC example on
stm32f103c8
but seems it does not works as expected.It just awaits infinitely here: https://github.com/embassy-rs/embassy/blob/94586576a06cf5869d0cdea6d678a0448bb1fdf8/examples/stm32f1/src/bin/adc.rs#L26
GDB shows me that
wfe
instruction was executed last but seems no events happening.