pub struct RingBufferedAdc<'d, T: Instance> { /* private fields */ }
Implementations§
Source§impl<'d, T: Instance> RingBufferedAdc<'d, T>
impl<'d, T: Instance> RingBufferedAdc<'d, T>
pub fn set_sample_sequence( &mut self, sequence: Sequence, channel: &mut impl AdcChannel<T>, sample_time: SampleTime, )
Sourcepub fn start(&mut self) -> Result<(), OverrunError>
pub fn start(&mut self) -> Result<(), OverrunError>
Turns on ADC if it is not already turned on and starts continuous DMA transfer.
Sourcepub fn teardown_adc(&mut self)
pub fn teardown_adc(&mut self)
Stops DMA transfer.
It does not turn off ADC.
Calling start
restarts continuous DMA transfer.
Sourcepub fn blocking_read<const N: usize>(
&mut self,
buf: &mut [u16; N],
) -> Result<usize, OverrunError>
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()
.
Sourcepub async fn read<const N: usize>(
&mut self,
measurements: &mut [u16; N],
) -> Result<usize, OverrunError>
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;
}