aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/adc/ringbuffered_v2.rs14
-rw-r--r--examples/stm32f4/src/bin/adc_dma.rs32
2 files changed, 29 insertions, 17 deletions
diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs
index e11311b9a..8c5eb9672 100644
--- a/embassy-stm32/src/adc/ringbuffered_v2.rs
+++ b/embassy-stm32/src/adc/ringbuffered_v2.rs
@@ -315,7 +315,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
315 /// 315 ///
316 /// Receive in the background is terminated if an error is returned. 316 /// Receive in the background is terminated if an error is returned.
317 /// It must then manually be started again by calling `start()` or by re-calling `read()`. 317 /// It must then manually be started again by calling `start()` or by re-calling `read()`.
318 pub async fn read<const N: usize>(&mut self, buf: &mut [u16; N]) -> Result<usize, OverrunError> { 318 pub fn read<const N: usize>(&mut self, buf: &mut [u16; N]) -> Result<usize, OverrunError> {
319 let r = T::regs(); 319 let r = T::regs();
320 320
321 // Start background receive if it was not already started 321 // Start background receive if it was not already started
@@ -325,11 +325,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
325 325
326 // Clear overrun flag if set. 326 // Clear overrun flag if set.
327 if r.sr().read().ovr() { 327 if r.sr().read().ovr() {
328 r.sr().modify(|regs| { 328 return self.stop(OverrunError);
329 regs.set_ovr(false);
330 // regs.set_eoc(false);
331 });
332 // return self.stop(OverrunError);
333 } 329 }
334 330
335 loop { 331 loop {
@@ -355,11 +351,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
355 351
356 // Clear overrun flag if set. 352 // Clear overrun flag if set.
357 if r.sr().read().ovr() { 353 if r.sr().read().ovr() {
358 r.sr().modify(|regs| { 354 return self.stop(OverrunError);
359 regs.set_ovr(false);
360 // regs.set_eoc(false);
361 });
362 // return self.stop(OverrunError);
363 } 355 }
364 match self.ring_buf.read_exact(buf).await { 356 match self.ring_buf.read_exact(buf).await {
365 Ok(len) => Ok(len), 357 Ok(len) => Ok(len),
diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs
index 88822a507..dd19caf1d 100644
--- a/examples/stm32f4/src/bin/adc_dma.rs
+++ b/examples/stm32f4/src/bin/adc_dma.rs
@@ -13,15 +13,18 @@ async fn main(_spawner: Spawner) {
13 let mut p = embassy_stm32::init(Default::default()); 13 let mut p = embassy_stm32::init(Default::default());
14 14
15 let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); 15 let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap();
16 let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap();
16 17
17 let adc = Adc::new(p.ADC1); 18 let adc = Adc::new(p.ADC1);
19 let adc2 = Adc::new(p.ADC2);
18 20
19 let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_data); 21 let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_data);
22 let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered(p.DMA2_CH2, adc_data2);
20 23
21 adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112); 24 adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112);
22 adc.set_sample_sequence(Sequence::Two, &mut p.PA2, SampleTime::CYCLES112); 25 adc.set_sample_sequence(Sequence::Two, &mut p.PA2, SampleTime::CYCLES112);
23 adc.set_sample_sequence(Sequence::Three, &mut p.PA1, SampleTime::CYCLES112); 26 adc2.set_sample_sequence(Sequence::One, &mut p.PA1, SampleTime::CYCLES112);
24 adc.set_sample_sequence(Sequence::Four, &mut p.PA3, SampleTime::CYCLES112); 27 adc2.set_sample_sequence(Sequence::Two, &mut p.PA3, SampleTime::CYCLES112);
25 28
26 // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around 29 // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around
27 // to the adc.read() call before the DMA buffer is wrapped around > 1 time. At this point, the overrun is so significant that the context of 30 // to the adc.read() call before the DMA buffer is wrapped around > 1 time. At this point, the overrun is so significant that the context of
@@ -31,10 +34,12 @@ async fn main(_spawner: Spawner) {
31 // An interrupt executor with a higher priority than other tasks may be a good approach here, allowing this task to wake and read the buffer most 34 // An interrupt executor with a higher priority than other tasks may be a good approach here, allowing this task to wake and read the buffer most
32 // frequently. 35 // frequently.
33 let mut tic = Instant::now(); 36 let mut tic = Instant::now();
34 let mut buffer1: [u16; 256] = [0u16; 256]; 37 let mut buffer1 = [0u16; 256];
38 let mut buffer2 = [0u16; 256];
35 let _ = adc.start(); 39 let _ = adc.start();
40 let _ = adc2.start();
36 loop { 41 loop {
37 match adc.read(&mut buffer1).await { 42 match adc.read_exact(&mut buffer1).await {
38 Ok(_data) => { 43 Ok(_data) => {
39 let toc = Instant::now(); 44 let toc = Instant::now();
40 info!( 45 info!(
@@ -49,10 +54,25 @@ async fn main(_spawner: Spawner) {
49 warn!("Error: {:?}", e); 54 warn!("Error: {:?}", e);
50 buffer1 = [0u16; 256]; 55 buffer1 = [0u16; 256];
51 let _ = adc.start(); 56 let _ = adc.start();
52 continue;
53 } 57 }
54 } 58 }
55 59
56 Timer::after_micros(300).await; 60 match adc2.read_exact(&mut buffer2).await {
61 Ok(_data) => {
62 let toc = Instant::now();
63 info!(
64 "\n adc2: {} dt = {}, n = {}",
65 buffer2[0..16],
66 (toc - tic).as_micros(),
67 _data
68 );
69 tic = toc;
70 }
71 Err(e) => {
72 warn!("Error: {:?}", e);
73 buffer2 = [0u16; 256];
74 let _ = adc2.start();
75 }
76 }
57 } 77 }
58} 78}