From f851081e09982a3edefd23082bb23143a0172464 Mon Sep 17 00:00:00 2001
From: Andres Vahter <andres@vahter.me>
Date: Wed, 3 Jul 2024 14:39:10 +0300
Subject: [PATCH] stm32 adc: introduce blocking_read

---
 embassy-stm32/src/adc/g4.rs                  |  2 +-
 embassy-stm32/src/adc/ringbuffered_v2.rs     | 20 ++++++-------
 embassy-stm32/src/adc/v2.rs                  |  2 +-
 embassy-stm32/src/adc/v3.rs                  | 30 ++++++++++++++++++--
 embassy-stm32/src/adc/v4.rs                  | 30 ++++++++++++++++++--
 examples/stm32f4/src/bin/adc.rs              |  8 +++---
 examples/stm32f4/src/bin/adc_dma.rs          |  4 +--
 examples/stm32f7/src/bin/adc.rs              |  4 +--
 examples/stm32g0/src/bin/adc.rs              |  4 +--
 examples/stm32g0/src/bin/adc_dma.rs          |  2 +-
 examples/stm32g0/src/bin/adc_oversampling.rs |  2 +-
 examples/stm32g4/src/bin/adc.rs              |  2 +-
 examples/stm32h7/src/bin/adc.rs              |  4 +--
 examples/stm32h7/src/bin/adc_dma.rs          |  2 +-
 examples/stm32l4/src/bin/adc.rs              |  2 +-
 examples/stm32u0/src/bin/adc.rs              |  2 +-
 tests/stm32/src/bin/dac.rs                   |  4 +--
 17 files changed, 86 insertions(+), 38 deletions(-)

diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 6569361fe..c1e584f59 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -258,7 +258,7 @@ impl<'d, T: Instance> Adc<'d, T> {
     }
 
     /// Read an ADC pin.
-    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+    pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
         channel.setup();
 
         self.read_channel(channel.channel())
diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs
index 92b34c3fd..3b064044e 100644
--- a/embassy-stm32/src/adc/ringbuffered_v2.rs
+++ b/embassy-stm32/src/adc/ringbuffered_v2.rs
@@ -97,10 +97,10 @@ impl<'d, T: Instance> Adc<'d, T> {
     /// The length of the `dma_buf` should be a multiple of the ADC channel count.
     /// For example, if 3 channels are measured, its length can be 3 * 40 = 120 measurements.
     ///
-    /// `read_exact` method is used to read out measurements from the DMA ring buffer, and its buffer should be exactly half of the `dma_buf` length.
-    /// It is critical to call `read_exact` frequently to prevent DMA buffer overrun.
+    /// `read` method is used to read out measurements from the DMA ring buffer, and its buffer should be exactly half of the `dma_buf` length.
+    /// It is critical to call `read` frequently to prevent DMA buffer overrun.
     ///
-    /// [`read_exact`]: #method.read_exact
+    /// [`read`]: #method.read
     pub fn into_ring_buffered(
         self,
         dma: impl Peripheral<P = impl RxDma<T>> + 'd,
@@ -331,7 +331,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
     ///
     /// 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()`.
-    pub fn 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> {
         let r = T::regs();
 
         // Start background receive if it was not already started
@@ -362,14 +362,14 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
     /// 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_exact` will populate the `measurements` array in the same order as the channels defined with `set_sample_sequence`.
+    /// 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_exact` again.
+    /// 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_exact`, measurements equivalent to half the size of the DMA buffer are still collected.
+    /// 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:
     /// ```rust,ignore
@@ -383,7 +383,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
     ///
     /// let mut measurements = [0u16; DMA_BUF_LEN / 2];
     /// loop {
-    ///     match adc.read_exact(&mut measurements).await {
+    ///     match adc.read(&mut measurements).await {
     ///         Ok(_) => {
     ///             defmt::info!("adc1: {}", measurements);
     ///             // Only needed to manually control sample rate.
@@ -391,7 +391,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
     ///         }
     ///         Err(e) => {
     ///             defmt::warn!("Error: {:?}", e);
-    ///             // DMA overrun, next call to `read_exact` restart ADC.
+    ///             // DMA overrun, next call to `read` restarts ADC.
     ///         }
     ///     }
     ///
@@ -404,7 +404,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
     /// [`set_sample_sequence`]: #method.set_sample_sequence
     /// [`teardown_adc`]: #method.teardown_adc
     /// [`start`]: #method.start
-    pub async fn read_exact<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> {
         assert_eq!(
             self.ring_buf.capacity() / 2,
             N,
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index ddeb7ea79..842a5ee6d 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -178,7 +178,7 @@ where
         T::regs().dr().read().0 as u16
     }
 
-    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+    pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
         channel.setup();
 
         // Configure ADC
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index c876bffea..9441e42ff 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -254,12 +254,36 @@ impl<'d, T: Instance> Adc<'d, T> {
     }
 
     /// Read an ADC channel.
-    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+    pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
         self.read_channel(channel)
     }
 
-    /// Asynchronously read from sequence of ADC channels.
-    pub async fn read_async(
+    /// Read one or multiple ADC channels using DMA.
+    ///
+    /// `sequence` iterator and `readings` must have the same length.
+    ///
+    /// Example
+    /// ```rust,ignore
+    /// use embassy_stm32::adc::{Adc, AdcChannel}
+    ///
+    /// let mut adc = Adc::new(p.ADC1);
+    /// let mut adc_pin0 = p.PA0.degrade_adc();
+    /// let mut adc_pin1 = p.PA1.degrade_adc();
+    /// let mut measurements = [0u16; 2];
+    ///
+    /// adc.read_async(
+    ///     p.DMA1_CH2,
+    ///     [
+    ///         (&mut *adc_pin0, SampleTime::CYCLES160_5),
+    ///         (&mut *adc_pin1, SampleTime::CYCLES160_5),
+    ///     ]
+    ///     .into_iter(),
+    ///     &mut measurements,
+    /// )
+    /// .await;
+    /// defmt::info!("measurements: {}", measurements);
+    /// ```
+    pub async fn read(
         &mut self,
         rx_dma: &mut impl RxDma<T>,
         sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 7db6fa4a2..63b5b58ea 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -318,12 +318,36 @@ impl<'d, T: Instance> Adc<'d, T> {
     }
 
     /// Read an ADC channel.
-    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+    pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
         self.read_channel(channel)
     }
 
-    /// Asynchronously read from sequence of ADC channels.
-    pub async fn read_async(
+    /// Read one or multiple ADC channels using DMA.
+    ///
+    /// `sequence` iterator and `readings` must have the same length.
+    ///
+    /// Example
+    /// ```rust,ignore
+    /// use embassy_stm32::adc::{Adc, AdcChannel}
+    ///
+    /// let mut adc = Adc::new(p.ADC1);
+    /// let mut adc_pin0 = p.PA0.degrade_adc();
+    /// let mut adc_pin2 = p.PA2.degrade_adc();
+    /// let mut measurements = [0u16; 2];
+    ///
+    /// adc.read_async(
+    ///     p.DMA2_CH0,
+    ///     [
+    ///         (&mut *adc_pin0, SampleTime::CYCLES112),
+    ///         (&mut *adc_pin2, SampleTime::CYCLES112),
+    ///     ]
+    ///     .into_iter(),
+    ///     &mut measurements,
+    /// )
+    /// .await;
+    /// defmt::info!("measurements: {}", measurements);
+    /// ```
+    pub async fn read(
         &mut self,
         rx_dma: &mut impl RxDma<T>,
         sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index 9473b7b7f..423d29225 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
     // Startup delay can be combined to the maximum of either
     delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
 
-    let vrefint_sample = adc.read(&mut vrefint);
+    let vrefint_sample = adc.blocking_read(&mut vrefint);
 
     let convert_to_millivolts = |sample| {
         // From http://www.st.com/resource/en/datasheet/DM00071990.pdf
@@ -50,16 +50,16 @@ async fn main(_spawner: Spawner) {
 
     loop {
         // Read pin
-        let v = adc.read(&mut pin);
+        let v = adc.blocking_read(&mut pin);
         info!("PC1: {} ({} mV)", v, convert_to_millivolts(v));
 
         // Read internal temperature
-        let v = adc.read(&mut temp);
+        let v = adc.blocking_read(&mut temp);
         let celcius = convert_to_celcius(v);
         info!("Internal temp: {} ({} C)", v, celcius);
 
         // Read internal voltage reference
-        let v = adc.read(&mut vrefint);
+        let v = adc.blocking_read(&mut vrefint);
         info!("VrefInt: {}", v);
 
         Timer::after_millis(100).await;
diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs
index 992bed573..43a761e6d 100644
--- a/examples/stm32f4/src/bin/adc_dma.rs
+++ b/examples/stm32f4/src/bin/adc_dma.rs
@@ -44,7 +44,7 @@ async fn adc_task(mut p: Peripherals) {
     let _ = adc.start();
     let _ = adc2.start();
     loop {
-        match adc.read_exact(&mut buffer1).await {
+        match adc.read(&mut buffer1).await {
             Ok(_data) => {
                 let toc = Instant::now();
                 info!(
@@ -62,7 +62,7 @@ async fn adc_task(mut p: Peripherals) {
             }
         }
 
-        match adc2.read_exact(&mut buffer2).await {
+        match adc2.read(&mut buffer2).await {
             Ok(_data) => {
                 let toc = Instant::now();
                 info!(
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs
index 641157960..6689e3b5d 100644
--- a/examples/stm32f7/src/bin/adc.rs
+++ b/examples/stm32f7/src/bin/adc.rs
@@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) {
     let mut pin = p.PA3;
 
     let mut vrefint = adc.enable_vrefint();
-    let vrefint_sample = adc.read(&mut vrefint);
+    let vrefint_sample = adc.blocking_read(&mut vrefint);
     let convert_to_millivolts = |sample| {
         // From http://www.st.com/resource/en/datasheet/DM00273119.pdf
         // 6.3.27 Reference voltage
@@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) {
     };
 
     loop {
-        let v = adc.read(&mut pin);
+        let v = adc.blocking_read(&mut pin);
         info!("--> {} - {} mV", v, convert_to_millivolts(v));
         Timer::after_millis(100).await;
     }
diff --git a/examples/stm32g0/src/bin/adc.rs b/examples/stm32g0/src/bin/adc.rs
index a35119e3d..6c7f3b48a 100644
--- a/examples/stm32g0/src/bin/adc.rs
+++ b/examples/stm32g0/src/bin/adc.rs
@@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) {
     let mut pin = p.PA1;
 
     let mut vrefint = adc.enable_vrefint();
-    let vrefint_sample = adc.read(&mut vrefint);
+    let vrefint_sample = adc.blocking_read(&mut vrefint);
     let convert_to_millivolts = |sample| {
         // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
         // 6.3.3 Embedded internal reference voltage
@@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) {
     };
 
     loop {
-        let v = adc.read(&mut pin);
+        let v = adc.blocking_read(&mut pin);
         info!("--> {} - {} mV", v, convert_to_millivolts(v));
         Timer::after_millis(100).await;
     }
diff --git a/examples/stm32g0/src/bin/adc_dma.rs b/examples/stm32g0/src/bin/adc_dma.rs
index 42d1e729b..3713e5a21 100644
--- a/examples/stm32g0/src/bin/adc_dma.rs
+++ b/examples/stm32g0/src/bin/adc_dma.rs
@@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) {
     let mut pa0 = p.PA0.degrade_adc();
 
     loop {
-        adc.read_async(
+        adc.read(
             &mut dma,
             [
                 (&mut vrefint_channel, SampleTime::CYCLES160_5),
diff --git a/examples/stm32g0/src/bin/adc_oversampling.rs b/examples/stm32g0/src/bin/adc_oversampling.rs
index 3c31eb206..9c5dd872a 100644
--- a/examples/stm32g0/src/bin/adc_oversampling.rs
+++ b/examples/stm32g0/src/bin/adc_oversampling.rs
@@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) {
     adc.oversampling_enable(true);
 
     loop {
-        let v = adc.read(&mut pin);
+        let v = adc.blocking_read(&mut pin);
         info!("--> {} ", v); //max 65520 = 0xFFF0
         Timer::after_millis(100).await;
     }
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 3de38cbd6..adca846d8 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
     adc.set_sample_time(SampleTime::CYCLES24_5);
 
     loop {
-        let measured = adc.read(&mut p.PA7);
+        let measured = adc.blocking_read(&mut p.PA7);
         info!("measured: {}", measured);
         Timer::after_millis(500).await;
     }
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index e9a857a74..98504ddf6 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -51,9 +51,9 @@ async fn main(_spawner: Spawner) {
     let mut vrefint_channel = adc.enable_vrefint();
 
     loop {
-        let vrefint = adc.read(&mut vrefint_channel);
+        let vrefint = adc.blocking_read(&mut vrefint_channel);
         info!("vrefint: {}", vrefint);
-        let measured = adc.read(&mut p.PC0);
+        let measured = adc.blocking_read(&mut p.PC0);
         info!("measured: {}", measured);
         Timer::after_millis(500).await;
     }
diff --git a/examples/stm32h7/src/bin/adc_dma.rs b/examples/stm32h7/src/bin/adc_dma.rs
index 6c0240453..0b905d227 100644
--- a/examples/stm32h7/src/bin/adc_dma.rs
+++ b/examples/stm32h7/src/bin/adc_dma.rs
@@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) {
     let mut pc0 = p.PC0.degrade_adc();
 
     loop {
-        adc.read_async(
+        adc.read(
             &mut dma,
             [
                 (&mut vrefint_channel, SampleTime::CYCLES387_5),
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index 7a89334e0..c557ac6d7 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -23,7 +23,7 @@ fn main() -> ! {
     let mut channel = p.PC0;
 
     loop {
-        let v = adc.read(&mut channel);
+        let v = adc.blocking_read(&mut channel);
         info!("--> {}", v);
     }
 }
diff --git a/examples/stm32u0/src/bin/adc.rs b/examples/stm32u0/src/bin/adc.rs
index 4410448f1..c8252e4e1 100644
--- a/examples/stm32u0/src/bin/adc.rs
+++ b/examples/stm32u0/src/bin/adc.rs
@@ -23,7 +23,7 @@ fn main() -> ! {
     let mut channel = p.PC0;
 
     loop {
-        let v = adc.read(&mut channel);
+        let v = adc.blocking_read(&mut channel);
         info!("--> {}", v);
         embassy_time::block_for(Duration::from_millis(200));
     }
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
index 06501ab14..86a68c530 100644
--- a/tests/stm32/src/bin/dac.rs
+++ b/tests/stm32/src/bin/dac.rs
@@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) {
     dac.set(Value::Bit8(0));
     // Now wait a little to obtain a stable value
     Timer::after_millis(30).await;
-    let offset = adc.read(&mut adc_pin);
+    let offset = adc.blocking_read(&mut adc_pin);
 
     for v in 0..=255 {
         // First set the DAC output value
@@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) {
         Timer::after_millis(30).await;
 
         // Need to steal the peripherals here because PA4 is obviously in use already
-        let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4);
+        let measured = adc.blocking_read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4);
         // Calibrate and normalize the measurement to get close to the dac_output_val
         let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;