pub struct Adc<'d, T: Instance, M: Mode> { /* private fields */ }Expand description
Analog to Digital driver.
Implementations§
Source§impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
Sourcepub fn enable_vrefint(&mut self) -> VrefIntwhere
T: HasInternalChannel<VrefInt>,
pub fn enable_vrefint(&mut self) -> VrefIntwhere
T: HasInternalChannel<VrefInt>,
Enable the internal voltage reference channel.
Sourcepub fn enable_temperature(&mut self) -> Temperaturewhere
T: HasInternalChannel<Temperature>,
pub fn enable_temperature(&mut self) -> Temperaturewhere
T: HasInternalChannel<Temperature>,
Enable the internal temperature sensor channel.
The sensor needs a long sample time (see the datasheet for ts_temp), and on some chips
shares its channel with VBAT: enabling both returns VBAT.
Sourcepub fn enable_vbat(&mut self) -> Vbatwhere
T: HasInternalChannel<Vbat>,
pub fn enable_vbat(&mut self) -> Vbatwhere
T: HasInternalChannel<Vbat>,
Enable the VBAT channel. This connects VBAT to an internal divider, which draws current
from the battery for as long as it is enabled; use disable_vbat
when done.
Sourcepub fn disable_vbat(&mut self, _vbat: Vbat)where
T: HasInternalChannel<Vbat>,
pub fn disable_vbat(&mut self, _vbat: Vbat)where
T: HasInternalChannel<Vbat>,
Disconnect the VBAT divider.
Sourcepub fn enable_vddcore(&mut self) -> VddCorewhere
T: HasInternalChannel<VddCore>,
pub fn enable_vddcore(&mut self) -> VddCorewhere
T: HasInternalChannel<VddCore>,
Enable the core supply voltage channel.
Sourcepub fn enable_dac(&mut self, dac_channel: u8) -> Dacwhere
T: HasInternalChannel<Dac>,
pub fn enable_dac(&mut self, dac_channel: u8) -> Dacwhere
T: HasInternalChannel<Dac>,
Enable the internal connection to the DAC output.
dac_channel selects which DAC output is connected on chips that mux several onto one ADC
channel (0 for OUT1, 1 for OUT2); it is ignored elsewhere.
Source§impl<'d, T: Instance<Regs = Adc>, M: Mode> Adc<'d, T, M>
impl<'d, T: Instance<Regs = Adc>, M: Mode> Adc<'d, T, M>
Sourcepub fn set_auto_off(&mut self, enable: bool)
pub fn set_auto_off(&mut self, enable: bool)
Enable or disable auto-off mode: the ADC powers itself off after each conversion and wakes up on the next start, at the cost of extra latency.
Source§impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
Sourcepub fn enable_watchdog(
&mut self,
watchdog: WatchdogIndex,
channels: WatchdogChannels,
low_threshold: u32,
high_threshold: u32,
) -> AnalogWatchdog<T, M>
pub fn enable_watchdog( &mut self, watchdog: WatchdogIndex, channels: WatchdogChannels, low_threshold: u32, high_threshold: u32, ) -> AnalogWatchdog<T, M>
Enable an analog watchdog and return a guard.
watchdog selects which of the hardware watchdogs to use. channels controls which ADC
channels are monitored; see WatchdogChannels for which variants are valid for each
watchdog. low_threshold and high_threshold are raw ADC counts in the same space as
the data register for the currently configured resolution and oversampling. The
watchdog fires when a sample falls outside [low_threshold, high_threshold].
Watchdogs 2 and 3 of 12-bit ADCs only compare the 8 most significant bits of a sample.
Call AnalogWatchdog::wait to detect threshold crossings concurrently with other
conversions, or AnalogWatchdog::monitor for self-contained single-pin monitoring
(which temporarily borrows the ADC).
§Panics
Panics if low_threshold > high_threshold, if the ADC does not have the requested
watchdog, or if a channel selection variant is used that is not supported by the chosen
watchdog.
Source§impl<'d, T: Instance> Adc<'d, T, Async>
impl<'d, T: Instance> Adc<'d, T, Async>
Sourcepub fn new(
adc: Peri<'d, T>,
_irqs: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
config: Config,
) -> Self
pub fn new( adc: Peri<'d, T>, _irqs: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd, config: Config, ) -> Self
Create a new ADC driver with its interrupt bound.
Sourcepub async fn read<'a>(
&mut self,
channel: impl BorrowedChannel<'a, T>,
sample_time: SampleTimeOf<T>,
) -> u16
pub async fn read<'a>( &mut self, channel: impl BorrowedChannel<'a, T>, sample_time: SampleTimeOf<T>, ) -> u16
Read a channel once, waiting for the end-of-conversion interrupt.
Source§impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
impl<'d, T: Instance, M: Mode> Adc<'d, T, M>
Sourcepub fn set_low_frequency_trigger(&mut self, enable: bool)
pub fn set_low_frequency_trigger(&mut self, enable: bool)
Enable or disable low-frequency trigger mode, required when hardware triggers arrive at less than about 1 kHz.
Sourcepub fn set_resolution(&mut self, resolution: Resolution)
pub fn set_resolution(&mut self, resolution: Resolution)
Set the conversion resolution.
Sourcepub fn resolution(&self) -> Resolution
pub fn resolution(&self) -> Resolution
The currently configured resolution.
Sourcepub fn sample_time_for_us(&self, us: u32) -> SampleTimeOf<T>where
T::Regs: SampleTimes,
pub fn sample_time_for_us(&self, us: u32) -> SampleTimeOf<T>where
T::Regs: SampleTimes,
Pick the shortest sample time that samples for at least us microseconds.
Sourcepub fn blocking_read<'a>(
&mut self,
channel: impl BorrowedChannel<'a, T>,
sample_time: SampleTimeOf<T>,
) -> u16
pub fn blocking_read<'a>( &mut self, channel: impl BorrowedChannel<'a, T>, sample_time: SampleTimeOf<T>, ) -> u16
Read a channel once, busy-waiting for the conversion.
Sourcepub async fn read_sequence<'a, 'ch: 'a, D: RxDma<T>>(
&mut self,
rx_dma: Peri<'a, D>,
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'a,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
trigger: Option<RegularAdcTrigger<T>>,
readings: &mut [u16],
)
pub async fn read_sequence<'a, 'ch: 'a, D: RxDma<T>>( &mut self, rx_dma: Peri<'a, D>, irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'a, sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>, trigger: Option<RegularAdcTrigger<T>>, readings: &mut [u16], )
Read one or multiple regular channels using DMA.
readings must have a length that is a multiple of the length of the sequence iterator;
the sequence is repeated until it is full, continuously or once per trigger event.
Example
use embassy_stm32::adc::{Adc, AdcChannel}
let mut adc = Adc::new_blocking(p.ADC1, Default::default());
let mut adc_pin0 = p.PA0.into();
let mut adc_pin1 = p.PA1.into();
let mut measurements = [0u16; 2];
adc.read_sequence(
p.DMA1_CH2.reborrow(),
Irqs,
[
(&mut *adc_pin0, SampleTime::CYCLES160_5),
(&mut *adc_pin1, SampleTime::CYCLES160_5),
]
.into_iter(),
None,
&mut measurements,
)
.await;
defmt::info!("measurements: {}", measurements);Note: the ADC is reconfigured on each call. Use configure_sequence
or into_ring_buffered to convert the same sequence repeatedly.
Note: ADCs without a fully configurable sequencer (F0, L0, and G0-class ADCs with more than 8 channels or channels above 14) can only scan channels in ascending or descending order, with a single sample time. This method panics if the hardware cannot deliver the requested sequence.
Sourcepub unsafe fn configure_transfer<'adc, 'ch, D: RxDma<T>, W: Word>(
&'adc mut self,
rx_dma: Peri<'adc, D>,
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'd,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
trigger: RegularAdcTrigger<T>,
dst: *mut W,
) -> ConfiguredTransfer<'adc, T::Regs>where
'ch: 'adc,
pub unsafe fn configure_transfer<'adc, 'ch, D: RxDma<T>, W: Word>(
&'adc mut self,
rx_dma: Peri<'adc, D>,
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'd,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
trigger: RegularAdcTrigger<T>,
dst: *mut W,
) -> ConfiguredTransfer<'adc, T::Regs>where
'ch: 'adc,
Configure an ADC channel sequence once and return a ConfiguredTransfer for repeated
DMA reads to peripherals such as FMAC or CORDIC.
Use Adc::configure_sequence instead if you don’t want to pipe the results directly
to a peripheral.
§Safety
dst must be a valid peripheral data register for the lifetime of the returned value.
§Notes
- The channel sequence is programmed into the ADC sequence registers once here and
remains fixed for the lifetime of the returned
ConfiguredTransfer. - Call this method AFTER the targeted peripheral is ready to begin receiving the transfer.
Sourcepub fn configure_sequence<'adc, 'ch, D: RxDma<T>>(
&'adc mut self,
rx_dma: Peri<'adc, D>,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'd,
) -> ConfiguredSequence<'adc, T::Regs>where
'ch: 'adc,
pub fn configure_sequence<'adc, 'ch, D: RxDma<T>>(
&'adc mut self,
rx_dma: Peri<'adc, D>,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'd,
) -> ConfiguredSequence<'adc, T::Regs>where
'ch: 'adc,
Configure an ADC channel sequence once and return a ConfiguredSequence for repeated
DMA reads without reprogramming the sequence each time.
Use Adc::read_sequence instead if you only need a single one-shot transfer.
§Parameters
rx_dma: The DMA channel to use for transfers.sequence: Iterator of channels and sample times.
§Returns
A ConfiguredSequence whose read method triggers one
DMA conversion of the pre-configured sequence per call.
Sourcepub fn into_ring_buffered<'a, 'ch, D: RxDma<T>>(
self,
dma: Peri<'a, D>,
dma_buf: &'a mut [u16],
irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'a,
sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>,
trigger: Option<RegularAdcTrigger<T>>,
) -> RingBufferedAdc<'a, T::Regs>
pub fn into_ring_buffered<'a, 'ch, D: RxDma<T>>( self, dma: Peri<'a, D>, dma_buf: &'a mut [u16], irq: impl Binding<D::Interrupt, InterruptHandler<D>> + 'a, sequence: impl ExactSizeIterator<Item = (BorrowedAdcChannel<'ch, T>, SampleTimeOf<T>)>, trigger: Option<RegularAdcTrigger<T>>, ) -> RingBufferedAdc<'a, T::Regs>
Configures the ADC to use a DMA ring buffer for continuous data acquisition.
Use the RingBufferedAdc::read method to retrieve measurements from the DMA ring buffer.
The read buffer should be exactly half the size of dma_buf. When using triggered mode, it
is recommended to configure dma_buf as a double buffer so that one half can be read while
the other half is being filled by the DMA, preventing data loss. The trigger period of the
ADC effectively defines the period at which the buffer should be read.
If continuous conversion mode is selected (no trigger), the provided dma_buf must be
large enough to prevent DMA buffer overruns. Its length should be a multiple of the number
of ADC channels being measured. For example, if 3 channels are measured and you want to
store 40 samples per channel, the buffer length should be 3 * 40 = 120.
Note: ADCs without a fully configurable sequencer (see read_sequence)
restrict the channel order and sample times; this method panics if the hardware cannot
deliver the requested sequence.