second adc added to example + API todos completed

This commit is contained in:
seth 2024-06-24 17:53:59 -07:00
parent 27b83fdbcf
commit 7056783fa2
2 changed files with 29 additions and 17 deletions

View File

@ -315,7 +315,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
/// ///
/// Receive in the background is terminated if an error is returned. /// Receive in the background is terminated if an error is returned.
/// It must then manually be started again by calling `start()` or by re-calling `read()`. /// It must then manually be started again by calling `start()` or by re-calling `read()`.
pub async fn read<const N: usize>(&mut self, buf: &mut [u16; N]) -> Result<usize, OverrunError> { pub fn read<const N: usize>(&mut self, buf: &mut [u16; N]) -> Result<usize, OverrunError> {
let r = T::regs(); let r = T::regs();
// Start background receive if it was not already started // Start background receive if it was not already started
@ -325,11 +325,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
// Clear overrun flag if set. // Clear overrun flag if set.
if r.sr().read().ovr() { if r.sr().read().ovr() {
r.sr().modify(|regs| { return self.stop(OverrunError);
regs.set_ovr(false);
// regs.set_eoc(false);
});
// return self.stop(OverrunError);
} }
loop { loop {
@ -355,11 +351,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
// Clear overrun flag if set. // Clear overrun flag if set.
if r.sr().read().ovr() { if r.sr().read().ovr() {
r.sr().modify(|regs| { return self.stop(OverrunError);
regs.set_ovr(false);
// regs.set_eoc(false);
});
// return self.stop(OverrunError);
} }
match self.ring_buf.read_exact(buf).await { match self.ring_buf.read_exact(buf).await {
Ok(len) => Ok(len), Ok(len) => Ok(len),

View File

@ -13,15 +13,18 @@ async fn main(_spawner: Spawner) {
let mut p = embassy_stm32::init(Default::default()); let mut p = embassy_stm32::init(Default::default());
let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); 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 adc = Adc::new(p.ADC1);
let adc2 = Adc::new(p.ADC2);
let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_data); let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_data);
let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered(p.DMA2_CH2, adc_data2);
adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112); adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112);
adc.set_sample_sequence(Sequence::Two, &mut p.PA2, SampleTime::CYCLES112); adc.set_sample_sequence(Sequence::Two, &mut p.PA2, SampleTime::CYCLES112);
adc.set_sample_sequence(Sequence::Three, &mut p.PA1, SampleTime::CYCLES112); adc2.set_sample_sequence(Sequence::One, &mut p.PA1, SampleTime::CYCLES112);
adc.set_sample_sequence(Sequence::Four, &mut p.PA3, SampleTime::CYCLES112); adc2.set_sample_sequence(Sequence::Two, &mut p.PA3, SampleTime::CYCLES112);
// Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around
// 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 // 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) {
// 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 // 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
// frequently. // frequently.
let mut tic = Instant::now(); let mut tic = Instant::now();
let mut buffer1: [u16; 256] = [0u16; 256]; let mut buffer1 = [0u16; 256];
let mut buffer2 = [0u16; 256];
let _ = adc.start(); let _ = adc.start();
let _ = adc2.start();
loop { loop {
match adc.read(&mut buffer1).await { match adc.read_exact(&mut buffer1).await {
Ok(_data) => { Ok(_data) => {
let toc = Instant::now(); let toc = Instant::now();
info!( info!(
@ -49,10 +54,25 @@ async fn main(_spawner: Spawner) {
warn!("Error: {:?}", e); warn!("Error: {:?}", e);
buffer1 = [0u16; 256]; buffer1 = [0u16; 256];
let _ = adc.start(); let _ = adc.start();
continue;
} }
} }
Timer::after_micros(300).await; match adc2.read_exact(&mut buffer2).await {
Ok(_data) => {
let toc = Instant::now();
info!(
"\n adc2: {} dt = {}, n = {}",
buffer2[0..16],
(toc - tic).as_micros(),
_data
);
tic = toc;
}
Err(e) => {
warn!("Error: {:?}", e);
buffer2 = [0u16; 256];
let _ = adc2.start();
}
}
} }
} }