embassy-stm32

Crates

git

Versions

stm32f469zg

Flavors

embassy_stm32::adc

Struct RingBufferedAdc

source
pub struct RingBufferedAdc<'d, T: Instance> { /* private fields */ }

Implementations§

source§

impl<'d, T: Instance> RingBufferedAdc<'d, T>

source

pub fn set_sample_sequence( &mut self, sequence: Sequence, channel: &mut impl AdcChannel<T>, sample_time: SampleTime, )

source

pub fn start(&mut self) -> Result<(), OverrunError>

Turns on ADC if it is not already turned on and starts continuous DMA transfer.

source

pub fn teardown_adc(&mut self)

Stops DMA transfer. It does not turn off ADC. Calling start restarts continuous DMA transfer.

source

pub fn blocking_read<const N: usize>( &mut self, buf: &mut [u16; N], ) -> Result<usize, OverrunError>

Read bytes that are readily available in the ring buffer. If no bytes are currently available in the buffer the call waits until the some bytes are available (at least one byte and at most half the buffer size)

Background receive is started if start() has not been previously called.

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().

source

pub async fn read<const N: usize>( &mut self, measurements: &mut [u16; N], ) -> Result<usize, OverrunError>

Reads measurements from the DMA ring buffer.

This method fills the provided measurements array with ADC readings from the DMA buffer. The length of the measurements array should be exactly half of the DMA buffer length. Because interrupts are only generated if half or full DMA transfer completes.

Each call to read will populate the measurements array in the same order as the channels defined with set_sample_sequence. There will be many sequences worth of measurements in this array because it only returns if at least half of the DMA buffer is filled. For example if 3 channels are sampled measurements contain: [sq0 sq1 sq3 sq0 sq1 sq3 sq0 sq1 sq3 sq0 sq1 sq3..].

If an error is returned, it indicates a DMA overrun, and the process must be restarted by calling start or read again.

By default, the ADC fills the DMA buffer as quickly as possible. To control the sample rate, call teardown_adc after each readout, and then start the DMA again at the desired interval. Note that even if using teardown_adc to control the sample rate, with each call to read, measurements equivalent to half the size of the DMA buffer are still collected.

Example:

const DMA_BUF_LEN: usize = 120;
let adc_dma_buf = [0u16; DMA_BUF_LEN];
let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_dma_buf);

adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112);
adc.set_sample_sequence(Sequence::Two, &mut p.PA1, SampleTime::CYCLES112);
adc.set_sample_sequence(Sequence::Three, &mut p.PA2, SampleTime::CYCLES112);

let mut measurements = [0u16; DMA_BUF_LEN / 2];
loop {
    match adc.read(&mut measurements).await {
        Ok(_) => {
            defmt::info!("adc1: {}", measurements);
            // Only needed to manually control sample rate.
            adc.teardown_adc();
        }
        Err(e) => {
            defmt::warn!("Error: {:?}", e);
            // DMA overrun, next call to `read` restarts ADC.
        }
    }

    // Manually control sample rate.
    Timer::after_millis(100).await;
}

Trait Implementations§

source§

impl<T: Instance> Drop for RingBufferedAdc<'_, T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'d, T> Freeze for RingBufferedAdc<'d, T>

§

impl<'d, T> RefUnwindSafe for RingBufferedAdc<'d, T>
where T: RefUnwindSafe,

§

impl<'d, T> Send for RingBufferedAdc<'d, T>
where T: Send,

§

impl<'d, T> Sync for RingBufferedAdc<'d, T>
where T: Sync,

§

impl<'d, T> Unpin for RingBufferedAdc<'d, T>
where T: Unpin,

§

impl<'d, T> !UnwindSafe for RingBufferedAdc<'d, T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.