From cd12c9cbceb0ba90a493194d8200b1d8e98bba1b Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Tue, 10 Oct 2023 18:10:53 +0200
Subject: [PATCH 01/16] stm32: add timeout to I2C driver

---
 embassy-stm32/Cargo.toml         |   8 +-
 embassy-stm32/src/i2c/mod.rs     |   5 -
 embassy-stm32/src/i2c/timeout.rs | 209 -------------------------------
 embassy-stm32/src/i2c/v2.rs      | 129 +++++++++++--------
 examples/stm32f4/src/bin/i2c.rs  |   8 +-
 examples/stm32h5/src/bin/i2c.rs  |   8 +-
 examples/stm32h7/src/bin/i2c.rs  |   8 +-
 7 files changed, 85 insertions(+), 290 deletions(-)
 delete mode 100644 embassy-stm32/src/i2c/timeout.rs

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 70e8f2e29..a4e4e51d6 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/"
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/"
 
-features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "time"]
+features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any"]
 flavors = [
     { regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" },
     { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
@@ -33,7 +33,7 @@ flavors = [
 
 [dependencies]
 embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
-embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
+embassy-time = { version = "0.1.3", path = "../embassy-time" }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
 embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@@ -87,7 +87,7 @@ default = ["rt"]
 rt = ["stm32-metapac/rt"]
 
 ## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
-defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
+defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"]
 
 exti = []
 low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ]
@@ -112,7 +112,7 @@ unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
 #! ## Time
 
 ## Enables additional driver features that depend on embassy-time
-time = ["dep:embassy-time"]
+time = []
 
 # Features starting with `_` are for internal use only. They're not intended
 # to be enabled by other crates, and are not covered by semver guarantees.
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 62d13e909..dde1a5040 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -7,11 +7,6 @@ use crate::interrupt;
 mod _version;
 pub use _version::*;
 
-#[cfg(feature = "time")]
-mod timeout;
-#[cfg(feature = "time")]
-pub use timeout::*;
-
 use crate::peripherals;
 
 #[derive(Debug, PartialEq, Eq)]
diff --git a/embassy-stm32/src/i2c/timeout.rs b/embassy-stm32/src/i2c/timeout.rs
deleted file mode 100644
index 103017cd1..000000000
--- a/embassy-stm32/src/i2c/timeout.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-use embassy_time::{Duration, Instant};
-
-use super::{Error, I2c, Instance};
-
-/// An I2C wrapper, which provides `embassy-time` based timeouts for all `embedded-hal` trait methods.
-///
-/// This is useful for recovering from a shorted bus or a device stuck in a clock stretching state.
-/// A regular [I2c] would freeze until condition is removed.
-pub struct TimeoutI2c<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> {
-    i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>,
-    timeout: Duration,
-}
-
-fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
-    let deadline = Instant::now() + timeout;
-    move || {
-        if Instant::now() > deadline {
-            Err(Error::Timeout)
-        } else {
-            Ok(())
-        }
-    }
-}
-
-impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
-    pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self {
-        Self { i2c, timeout }
-    }
-
-    // =========================
-    //  Async public API
-
-    #[cfg(i2c_v2)]
-    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
-    where
-        TXDMA: crate::i2c::TxDma<T>,
-    {
-        self.write_timeout(address, write, self.timeout).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
-    where
-        TXDMA: crate::i2c::TxDma<T>,
-    {
-        self.i2c.write_timeout(address, write, timeout_fn(timeout)).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
-    where
-        TXDMA: crate::i2c::TxDma<T>,
-    {
-        self.write_vectored_timeout(address, write, self.timeout).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
-    where
-        TXDMA: crate::i2c::TxDma<T>,
-    {
-        self.i2c
-            .write_vectored_timeout(address, write, timeout_fn(timeout))
-            .await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
-    where
-        RXDMA: crate::i2c::RxDma<T>,
-    {
-        self.read_timeout(address, buffer, self.timeout).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
-    where
-        RXDMA: crate::i2c::RxDma<T>,
-    {
-        self.i2c.read_timeout(address, buffer, timeout_fn(timeout)).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
-    where
-        TXDMA: super::TxDma<T>,
-        RXDMA: super::RxDma<T>,
-    {
-        self.write_read_timeout(address, write, read, self.timeout).await
-    }
-
-    #[cfg(i2c_v2)]
-    pub async fn write_read_timeout(
-        &mut self,
-        address: u8,
-        write: &[u8],
-        read: &mut [u8],
-        timeout: Duration,
-    ) -> Result<(), Error>
-    where
-        TXDMA: super::TxDma<T>,
-        RXDMA: super::RxDma<T>,
-    {
-        self.i2c
-            .write_read_timeout(address, write, read, timeout_fn(timeout))
-            .await
-    }
-
-    // =========================
-    //  Blocking public API
-
-    /// Blocking read with a custom timeout
-    pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
-        self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout))
-    }
-
-    /// Blocking read with default timeout, provided in [`TimeoutI2c::new()`]
-    pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_read_timeout(addr, read, self.timeout)
-    }
-
-    /// Blocking write with a custom timeout
-    pub fn blocking_write_timeout(&mut self, addr: u8, write: &[u8], timeout: Duration) -> Result<(), Error> {
-        self.i2c.blocking_write_timeout(addr, write, timeout_fn(timeout))
-    }
-
-    /// Blocking write with default timeout, provided in [`TimeoutI2c::new()`]
-    pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> {
-        self.blocking_write_timeout(addr, write, self.timeout)
-    }
-
-    /// Blocking write-read with a custom timeout
-    pub fn blocking_write_read_timeout(
-        &mut self,
-        addr: u8,
-        write: &[u8],
-        read: &mut [u8],
-        timeout: Duration,
-    ) -> Result<(), Error> {
-        self.i2c
-            .blocking_write_read_timeout(addr, write, read, timeout_fn(timeout))
-    }
-
-    /// Blocking write-read with default timeout, provided in [`TimeoutI2c::new()`]
-    pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_write_read_timeout(addr, write, read, self.timeout)
-    }
-}
-
-impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read
-    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
-{
-    type Error = Error;
-
-    fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> {
-        self.blocking_read(addr, read)
-    }
-}
-
-impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write
-    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
-{
-    type Error = Error;
-
-    fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> {
-        self.blocking_write(addr, write)
-    }
-}
-
-impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead
-    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
-{
-    type Error = Error;
-
-    fn write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
-        self.blocking_write_read(addr, write, read)
-    }
-}
-
-#[cfg(feature = "unstable-traits")]
-mod eh1 {
-    use super::*;
-
-    impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
-        type Error = Error;
-    }
-
-    impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
-        fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_read(address, read)
-        }
-
-        fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
-            self.blocking_write(address, write)
-        }
-
-        fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_write_read(address, write, read)
-        }
-
-        fn transaction(
-            &mut self,
-            _address: u8,
-            _operations: &mut [embedded_hal_1::i2c::Operation<'_>],
-        ) -> Result<(), Self::Error> {
-            todo!();
-        }
-    }
-}
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 543d8f1b4..256b39638 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -7,6 +7,7 @@ use embassy_embedded_hal::SetConfig;
 use embassy_hal_internal::drop::OnDrop;
 use embassy_hal_internal::{into_ref, PeripheralRef};
 use embassy_sync::waitqueue::AtomicWaker;
+use embassy_time::{Duration, Instant};
 
 use crate::dma::{NoDma, Transfer};
 use crate::gpio::sealed::AFType;
@@ -43,6 +44,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 pub struct Config {
     pub sda_pullup: bool,
     pub scl_pullup: bool,
+    pub transaction_timeout: Duration,
 }
 
 impl Default for Config {
@@ -50,6 +52,7 @@ impl Default for Config {
         Self {
             sda_pullup: false,
             scl_pullup: false,
+            transaction_timeout: Duration::from_millis(100),
         }
     }
 }
@@ -71,6 +74,7 @@ pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
     tx_dma: PeripheralRef<'d, TXDMA>,
     #[allow(dead_code)]
     rx_dma: PeripheralRef<'d, RXDMA>,
+    timeout: Duration,
 }
 
 impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
@@ -132,6 +136,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
             _peri: peri,
             tx_dma,
             rx_dma,
+            timeout: config.transaction_timeout,
         }
     }
 
@@ -598,22 +603,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     where
         TXDMA: crate::i2c::TxDma<T>,
     {
-        self.write_timeout(address, write, || Ok(())).await
+        self.write_timeout(address, write, self.timeout).await
     }
 
-    pub async fn write_timeout(
-        &mut self,
-        address: u8,
-        write: &[u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
-    ) -> Result<(), Error>
+    pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
     {
         if write.is_empty() {
-            self.write_internal(address, write, true, check_timeout)
+            self.write_internal(address, write, true, timeout_fn(timeout))
         } else {
-            self.write_dma_internal(address, write, true, true, check_timeout).await
+            embassy_time::with_timeout(
+                timeout,
+                self.write_dma_internal(address, write, true, true, timeout_fn(timeout)),
+            )
+            .await
+            .unwrap_or(Err(Error::Timeout))
         }
     }
 
@@ -621,15 +626,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     where
         TXDMA: crate::i2c::TxDma<T>,
     {
-        self.write_vectored_timeout(address, write, || Ok(())).await
+        self.write_vectored_timeout(address, write, self.timeout).await
     }
 
-    pub async fn write_vectored_timeout(
-        &mut self,
-        address: u8,
-        write: &[&[u8]],
-        check_timeout: impl Fn() -> Result<(), Error>,
-    ) -> Result<(), Error>
+    pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
     {
@@ -644,8 +644,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
             let next = iter.next();
             let is_last = next.is_none();
 
-            self.write_dma_internal(address, c, first, is_last, || check_timeout())
-                .await?;
+            embassy_time::with_timeout(
+                timeout,
+                self.write_dma_internal(address, c, first, is_last, timeout_fn(timeout)),
+            )
+            .await
+            .unwrap_or(Err(Error::Timeout))?;
             first = false;
             current = next;
         }
@@ -656,22 +660,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     where
         RXDMA: crate::i2c::RxDma<T>,
     {
-        self.read_timeout(address, buffer, || Ok(())).await
+        self.read_timeout(address, buffer, self.timeout).await
     }
 
-    pub async fn read_timeout(
-        &mut self,
-        address: u8,
-        buffer: &mut [u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
-    ) -> Result<(), Error>
+    pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
     where
         RXDMA: crate::i2c::RxDma<T>,
     {
         if buffer.is_empty() {
-            self.read_internal(address, buffer, false, check_timeout)
+            self.read_internal(address, buffer, false, timeout_fn(timeout))
         } else {
-            self.read_dma_internal(address, buffer, false, check_timeout).await
+            embassy_time::with_timeout(
+                timeout,
+                self.read_dma_internal(address, buffer, false, timeout_fn(timeout)),
+            )
+            .await
+            .unwrap_or(Err(Error::Timeout))
         }
     }
 
@@ -680,7 +684,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         TXDMA: super::TxDma<T>,
         RXDMA: super::RxDma<T>,
     {
-        self.write_read_timeout(address, write, read, || Ok(())).await
+        self.write_read_timeout(address, write, read, self.timeout).await
     }
 
     pub async fn write_read_timeout(
@@ -688,23 +692,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         address: u8,
         write: &[u8],
         read: &mut [u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
+        timeout: Duration,
     ) -> Result<(), Error>
     where
         TXDMA: super::TxDma<T>,
         RXDMA: super::RxDma<T>,
     {
+        let start_instant = Instant::now();
+        let check_timeout = timeout_fn(timeout);
         if write.is_empty() {
-            self.write_internal(address, write, false, || check_timeout())?;
+            self.write_internal(address, write, false, &check_timeout)?;
         } else {
-            self.write_dma_internal(address, write, true, true, || check_timeout())
-                .await?;
+            embassy_time::with_timeout(
+                timeout,
+                self.write_dma_internal(address, write, true, true, &check_timeout),
+            )
+            .await
+            .unwrap_or(Err(Error::Timeout))?;
         }
 
+        let time_left_until_timeout = timeout - Instant::now().duration_since(start_instant);
+
         if read.is_empty() {
-            self.read_internal(address, read, true, check_timeout)?;
+            self.read_internal(address, read, true, &check_timeout)?;
         } else {
-            self.read_dma_internal(address, read, true, check_timeout).await?;
+            embassy_time::with_timeout(
+                time_left_until_timeout,
+                self.read_dma_internal(address, read, true, &check_timeout),
+            )
+            .await
+            .unwrap_or(Err(Error::Timeout))?;
         }
 
         Ok(())
@@ -713,31 +730,21 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     // =========================
     //  Blocking public API
 
-    pub fn blocking_read_timeout(
-        &mut self,
-        address: u8,
-        read: &mut [u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
-    ) -> Result<(), Error> {
-        self.read_internal(address, read, false, &check_timeout)
+    pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
+        self.read_internal(address, read, false, timeout_fn(timeout))
         // Automatic Stop
     }
 
     pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_read_timeout(address, read, || Ok(()))
+        self.blocking_read_timeout(address, read, self.timeout)
     }
 
-    pub fn blocking_write_timeout(
-        &mut self,
-        address: u8,
-        write: &[u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
-    ) -> Result<(), Error> {
-        self.write_internal(address, write, true, &check_timeout)
+    pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> {
+        self.write_internal(address, write, true, timeout_fn(timeout))
     }
 
     pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
-        self.blocking_write_timeout(address, write, || Ok(()))
+        self.blocking_write_timeout(address, write, self.timeout)
     }
 
     pub fn blocking_write_read_timeout(
@@ -745,26 +752,29 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         address: u8,
         write: &[u8],
         read: &mut [u8],
-        check_timeout: impl Fn() -> Result<(), Error>,
+        timeout: Duration,
     ) -> Result<(), Error> {
+        let check_timeout = timeout_fn(timeout);
         self.write_internal(address, write, false, &check_timeout)?;
         self.read_internal(address, read, true, &check_timeout)
         // Automatic Stop
     }
 
     pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_write_read_timeout(address, write, read, || Ok(()))
+        self.blocking_write_read_timeout(address, write, read, self.timeout)
     }
 
     pub fn blocking_write_vectored_timeout(
         &mut self,
         address: u8,
         write: &[&[u8]],
-        check_timeout: impl Fn() -> Result<(), Error>,
+        timeout: Duration,
     ) -> Result<(), Error> {
         if write.is_empty() {
             return Err(Error::ZeroLengthTransfer);
         }
+
+        let check_timeout = timeout_fn(timeout);
         let first_length = write[0].len();
         let last_slice_index = write.len() - 1;
 
@@ -834,7 +844,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
-        self.blocking_write_vectored_timeout(address, write, || Ok(()))
+        self.blocking_write_vectored_timeout(address, write, self.timeout)
     }
 }
 
@@ -1089,3 +1099,14 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> {
         Ok(())
     }
 }
+
+fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
+    let deadline = Instant::now() + timeout;
+    move || {
+        if Instant::now() > deadline {
+            Err(Error::Timeout)
+        } else {
+            Ok(())
+        }
+    }
+}
diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs
index a92957325..10ca2bdc7 100644
--- a/examples/stm32f4/src/bin/i2c.rs
+++ b/examples/stm32f4/src/bin/i2c.rs
@@ -5,7 +5,7 @@
 use defmt::*;
 use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
-use embassy_stm32::i2c::{Error, I2c, TimeoutI2c};
+use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
 use embassy_time::Duration;
@@ -34,13 +34,9 @@ async fn main(_spawner: Spawner) {
         Default::default(),
     );
 
-    // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long.
-    // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay.
-    let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000));
-
     let mut data = [0u8; 1];
 
-    match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
+    match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
         Ok(()) => info!("Whoami: {}", data[0]),
         Err(Error::Timeout) => error!("Operation timed out"),
         Err(e) => error!("I2c Error: {:?}", e),
diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs
index 8b6fe71ae..4ce378e9b 100644
--- a/examples/stm32h5/src/bin/i2c.rs
+++ b/examples/stm32h5/src/bin/i2c.rs
@@ -4,7 +4,7 @@
 
 use defmt::*;
 use embassy_executor::Spawner;
-use embassy_stm32::i2c::{Error, I2c, TimeoutI2c};
+use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
 use embassy_time::Duration;
@@ -33,13 +33,9 @@ async fn main(_spawner: Spawner) {
         Default::default(),
     );
 
-    // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long.
-    // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay.
-    let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000));
-
     let mut data = [0u8; 1];
 
-    match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
+    match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
         Ok(()) => info!("Whoami: {}", data[0]),
         Err(Error::Timeout) => error!("Operation timed out"),
         Err(e) => error!("I2c Error: {:?}", e),
diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs
index c2979c59b..7cd12e5eb 100644
--- a/examples/stm32h7/src/bin/i2c.rs
+++ b/examples/stm32h7/src/bin/i2c.rs
@@ -4,7 +4,7 @@
 
 use defmt::*;
 use embassy_executor::Spawner;
-use embassy_stm32::i2c::{Error, I2c, TimeoutI2c};
+use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
 use embassy_time::Duration;
@@ -33,13 +33,9 @@ async fn main(_spawner: Spawner) {
         Default::default(),
     );
 
-    // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long.
-    // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay.
-    let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000));
-
     let mut data = [0u8; 1];
 
-    match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
+    match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) {
         Ok(()) => info!("Whoami: {}", data[0]),
         Err(Error::Timeout) => error!("Operation timed out"),
         Err(e) => error!("I2c Error: {:?}", e),

From bfcca79c1e51a5cae6c5c40018b4a923e798c5ca Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 22:12:03 +0200
Subject: [PATCH 02/16] Add time feature back and gate i2c on time

---
 embassy-stm32/Cargo.toml     | 8 ++++----
 embassy-stm32/src/i2c/mod.rs | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index a4e4e51d6..70e8f2e29 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/"
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/"
 
-features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any"]
+features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "time"]
 flavors = [
     { regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" },
     { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
@@ -33,7 +33,7 @@ flavors = [
 
 [dependencies]
 embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
-embassy-time = { version = "0.1.3", path = "../embassy-time" }
+embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
 embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@@ -87,7 +87,7 @@ default = ["rt"]
 rt = ["stm32-metapac/rt"]
 
 ## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
-defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"]
+defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
 
 exti = []
 low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ]
@@ -112,7 +112,7 @@ unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
 #! ## Time
 
 ## Enables additional driver features that depend on embassy-time
-time = []
+time = ["dep:embassy-time"]
 
 # Features starting with `_` are for internal use only. They're not intended
 # to be enabled by other crates, and are not covered by semver guarantees.
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index dde1a5040..c35f59977 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -3,7 +3,7 @@
 use crate::interrupt;
 
 #[cfg_attr(i2c_v1, path = "v1.rs")]
-#[cfg_attr(i2c_v2, path = "v2.rs")]
+#[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")]
 mod _version;
 pub use _version::*;
 

From 1cd3ae9bd51a34a29b0d34374f8ecc08b9b830f9 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 22:20:17 +0200
Subject: [PATCH 03/16] Add comment about feature gate on I2C mod

---
 embassy-stm32/src/i2c/mod.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index c35f59977..d5bb2ed21 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -2,6 +2,8 @@
 
 use crate::interrupt;
 
+// I2C V2 is gated on the `time` feature because timing facilities are necessary
+// to provide timeout functionality in order to prevent some APIs from stalling indefinitely
 #[cfg_attr(i2c_v1, path = "v1.rs")]
 #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")]
 mod _version;

From 7b1cd4293637a0da1c57a12976349715a27e2d04 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 22:20:27 +0200
Subject: [PATCH 04/16] Add time feature to CI

---
 ci.sh        | 112 +++++++++++++++++++++++++--------------------------
 ci_stable.sh |  66 +++++++++++++++---------------
 2 files changed, 89 insertions(+), 89 deletions(-)

diff --git a/ci.sh b/ci.sh
index 332222982..4098743f4 100755
--- a/ci.sh
+++ b/ci.sh
@@ -69,62 +69,62 @@ cargo batch  \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,intrinsics \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,qspi-as-gpio \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\
     --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
     --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
diff --git a/ci_stable.sh b/ci_stable.sh
index 4ee5f4106..61b02175f 100755
--- a/ci_stable.sh
+++ b/ci_stable.sh
@@ -35,38 +35,38 @@ cargo batch  \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf52840 --bin raw_spawn \
     --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --no-default-features --out-dir out/examples/stm32l0 --bin raw_spawn \

From ee93bbf1d45226ae71234287c382bf1ed530ca97 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 22:45:54 +0200
Subject: [PATCH 05/16] Gate pub use _version::*

---
 embassy-stm32/src/i2c/mod.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index d5bb2ed21..61989c239 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -7,6 +7,8 @@ use crate::interrupt;
 #[cfg_attr(i2c_v1, path = "v1.rs")]
 #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")]
 mod _version;
+
+#[cfg(any(i2c_v1, all(i2c_v2, feature = "time")))]
 pub use _version::*;
 
 use crate::peripherals;

From b6c0ddb7df86a8c5531ef6ae4c026b2e7175c96b Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:05:12 +0200
Subject: [PATCH 06/16] Move the feature gates to the i2c module instead of the
 pub use statement

---
 embassy-stm32/src/i2c/mod.rs | 2 --
 embassy-stm32/src/lib.rs     | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 61989c239..d5bb2ed21 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -7,8 +7,6 @@ use crate::interrupt;
 #[cfg_attr(i2c_v1, path = "v1.rs")]
 #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")]
 mod _version;
-
-#[cfg(any(i2c_v1, all(i2c_v2, feature = "time")))]
 pub use _version::*;
 
 use crate::peripherals;
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index e883678b5..cfb78da3d 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -41,7 +41,7 @@ pub mod flash;
 pub mod fmc;
 #[cfg(hrtim)]
 pub mod hrtim;
-#[cfg(i2c)]
+#[cfg(all(i2c, any(i2c_v1, all(i2c_v2, feature = "time"))))]
 pub mod i2c;
 #[cfg(all(spi_v1, rcc_f4))]
 pub mod i2s;

From cd68f85501fabaf22587a900e60c70b6dae43767 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:25:13 +0200
Subject: [PATCH 07/16] Added guards to individual APIs

---
 embassy-stm32/src/i2c/mod.rs |  2 +-
 embassy-stm32/src/i2c/v2.rs  | 94 ++++++++++++++++++++++++++++++++----
 embassy-stm32/src/lib.rs     |  2 +-
 3 files changed, 86 insertions(+), 12 deletions(-)

diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index d5bb2ed21..204ad679d 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -5,7 +5,7 @@ use crate::interrupt;
 // I2C V2 is gated on the `time` feature because timing facilities are necessary
 // to provide timeout functionality in order to prevent some APIs from stalling indefinitely
 #[cfg_attr(i2c_v1, path = "v1.rs")]
-#[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")]
+#[cfg_attr(i2c_v2, path = "v2.rs")]
 mod _version;
 pub use _version::*;
 
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 256b39638..33c397404 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -44,6 +44,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 pub struct Config {
     pub sda_pullup: bool,
     pub scl_pullup: bool,
+    #[cfg(feature = "time")]
     pub transaction_timeout: Duration,
 }
 
@@ -52,6 +53,7 @@ impl Default for Config {
         Self {
             sda_pullup: false,
             scl_pullup: false,
+            #[cfg(feature = "time")]
             transaction_timeout: Duration::from_millis(100),
         }
     }
@@ -74,6 +76,7 @@ pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
     tx_dma: PeripheralRef<'d, TXDMA>,
     #[allow(dead_code)]
     rx_dma: PeripheralRef<'d, RXDMA>,
+    #[cfg(feature = "time")]
     timeout: Duration,
 }
 
@@ -136,6 +139,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
             _peri: peri,
             tx_dma,
             rx_dma,
+            #[cfg(feature = "time")]
             timeout: config.transaction_timeout,
         }
     }
@@ -599,6 +603,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     // =========================
     //  Async public API
 
+    #[cfg(feature = "time")]
     pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
@@ -606,6 +611,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.write_timeout(address, write, self.timeout).await
     }
 
+    #[cfg(feature = "time")]
     pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
@@ -622,6 +628,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         }
     }
 
+    #[cfg(feature = "time")]
     pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
@@ -629,6 +636,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.write_vectored_timeout(address, write, self.timeout).await
     }
 
+    #[cfg(feature = "time")]
     pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
     where
         TXDMA: crate::i2c::TxDma<T>,
@@ -656,6 +664,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         Ok(())
     }
 
+    #[cfg(feature = "time")]
     pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
     where
         RXDMA: crate::i2c::RxDma<T>,
@@ -663,6 +672,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.read_timeout(address, buffer, self.timeout).await
     }
 
+    #[cfg(feature = "time")]
     pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
     where
         RXDMA: crate::i2c::RxDma<T>,
@@ -679,6 +689,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         }
     }
 
+    #[cfg(feature = "time")]
     pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
     where
         TXDMA: super::TxDma<T>,
@@ -687,6 +698,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.write_read_timeout(address, write, read, self.timeout).await
     }
 
+    #[cfg(feature = "time")]
     pub async fn write_read_timeout(
         &mut self,
         address: u8,
@@ -730,23 +742,43 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     // =========================
     //  Blocking public API
 
+    #[cfg(feature = "time")]
     pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
         self.read_internal(address, read, false, timeout_fn(timeout))
         // Automatic Stop
     }
 
-    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_read_timeout(address, read, self.timeout)
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> {
+        self.read_internal(address, read, false, check_timeout)
+        // Automatic Stop
     }
 
+    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
+        #[cfg(feature = "time")]
+        self.blocking_read_timeout(address, read, self.timeout)
+        #[cfg(not(feature = "time"))]
+        self.blocking_read_timeout(address, read, || Ok(()))
+    }
+
+    #[cfg(feature = "time")]
     pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> {
         self.write_internal(address, write, true, timeout_fn(timeout))
     }
 
-    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
-        self.blocking_write_timeout(address, write, self.timeout)
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> {
+        self.write_internal(address, write, true, check_timeout)
     }
 
+    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
+        #[cfg(feature = "time")]
+        self.blocking_write_timeout(address, write, self.timeout)
+        #[cfg(not(feature = "time"))]
+        self.blocking_write_timeout(address, write, || Ok(()))
+    }
+
+    #[cfg(feature = "time")]
     pub fn blocking_write_read_timeout(
         &mut self,
         address: u8,
@@ -760,21 +792,37 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         // Automatic Stop
     }
 
-    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        self.blocking_write_read_timeout(address, write, read, self.timeout)
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write_read_timeout(
+        &mut self,
+        address: u8,
+        write: &[u8],
+        read: &mut [u8],
+        check_timeout: impl Fn() -> Result<(), Error>,
+    ) -> Result<(), Error> {
+        let check_timeout = timeout_fn(timeout);
+        self.write_internal(address, write, false, &check_timeout)?;
+        self.read_internal(address, read, true, &check_timeout)
+        // Automatic Stop
     }
 
-    pub fn blocking_write_vectored_timeout(
+    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
+        #[cfg(feature = "time")]
+        self.blocking_write_read_timeout(address, write, read, self.timeout)
+        #[cfg(not(feature = "time"))]
+        self.blocking_write_read_timeout(address, write, read, || Ok(()))
+    }
+
+    fn blocking_write_vectored_with_timeout(
         &mut self,
         address: u8,
         write: &[&[u8]],
-        timeout: Duration,
+        check_timeout: impl Fn() -> Result<(), Error>,
     ) -> Result<(), Error> {
         if write.is_empty() {
             return Err(Error::ZeroLengthTransfer);
         }
 
-        let check_timeout = timeout_fn(timeout);
         let first_length = write[0].len();
         let last_slice_index = write.len() - 1;
 
@@ -843,8 +891,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         result
     }
 
+    #[cfg(feature = "time")]
+    pub fn blocking_write_vectored_timeout(
+        &mut self,
+        address: u8,
+        write: &[&[u8]],
+        timeout: Duration,
+    ) -> Result<(), Error> {
+        let check_timeout = timeout_fn(timeout);
+        self.blocking_write_vectored_with_timeout(address, write, check_timeout)
+    }
+
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write_vectored_timeout(
+        &mut self,
+        address: u8,
+        write: &[&[u8]],
+        check_timeout: impl Fn() -> Result<(), Error>,
+    ) -> Result<(), Error> {
+        self.blocking_write_vectored_with_timeout(address, write, check_timeout)
+    }
+
     pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
+        #[cfg(feature = "time")]
         self.blocking_write_vectored_timeout(address, write, self.timeout)
+        #[cfg(not(feature = "time"))]
+        self.blocking_write_vectored_timeout(address, write, || Ok(()))
     }
 }
 
@@ -854,6 +926,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> {
     }
 }
 
+#[cfg(feature = "time")]
 mod eh02 {
     use super::*;
 
@@ -1053,7 +1126,7 @@ mod eh1 {
     }
 }
 
-#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
+#[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "time"))]
 mod eha {
     use super::super::{RxDma, TxDma};
     use super::*;
@@ -1100,6 +1173,7 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> {
     }
 }
 
+#[cfg(feature = "time")]
 fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
     let deadline = Instant::now() + timeout;
     move || {
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index cfb78da3d..e883678b5 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -41,7 +41,7 @@ pub mod flash;
 pub mod fmc;
 #[cfg(hrtim)]
 pub mod hrtim;
-#[cfg(all(i2c, any(i2c_v1, all(i2c_v2, feature = "time"))))]
+#[cfg(i2c)]
 pub mod i2c;
 #[cfg(all(spi_v1, rcc_f4))]
 pub mod i2s;

From 251d004708762210a2279bee66c1e5b2dcdf93cb Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:32:40 +0200
Subject: [PATCH 08/16] Try using cfg! macro

---
 embassy-stm32/src/i2c/v2.rs | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 33c397404..6627d7f67 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -755,10 +755,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
-        #[cfg(feature = "time")]
-        self.blocking_read_timeout(address, read, self.timeout)
-        #[cfg(not(feature = "time"))]
-        self.blocking_read_timeout(address, read, || Ok(()))
+        if cfg!(feature = "time") {
+            self.blocking_read_timeout(address, read, self.timeout)
+        } else {
+            self.blocking_read_timeout(address, read, || Ok(()))
+        }
     }
 
     #[cfg(feature = "time")]
@@ -772,10 +773,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
-        #[cfg(feature = "time")]
-        self.blocking_write_timeout(address, write, self.timeout)
-        #[cfg(not(feature = "time"))]
-        self.blocking_write_timeout(address, write, || Ok(()))
+        if cfg!(feature = "time") {
+            self.blocking_write_timeout(address, write, self.timeout)
+        } else {
+            self.blocking_write_timeout(address, write, || Ok(()))
+        }
     }
 
     #[cfg(feature = "time")]
@@ -807,10 +809,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        #[cfg(feature = "time")]
-        self.blocking_write_read_timeout(address, write, read, self.timeout)
-        #[cfg(not(feature = "time"))]
-        self.blocking_write_read_timeout(address, write, read, || Ok(()))
+        if cfg!(feature = "time") {
+            self.blocking_write_read_timeout(address, write, read, self.timeout)
+        } else {
+            self.blocking_write_read_timeout(address, write, read, || Ok(()))
+        }
     }
 
     fn blocking_write_vectored_with_timeout(
@@ -913,10 +916,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
-        #[cfg(feature = "time")]
-        self.blocking_write_vectored_timeout(address, write, self.timeout)
-        #[cfg(not(feature = "time"))]
-        self.blocking_write_vectored_timeout(address, write, || Ok(()))
+        if cfg!(feature = "time") {
+            self.blocking_write_vectored_timeout(address, write, self.timeout)
+        } else {
+            self.blocking_write_vectored_timeout(address, write, || Ok(()))
+        }
     }
 }
 

From ee5ea7aa06491a2bbd523ac054604977cb0c9e33 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:34:02 +0200
Subject: [PATCH 09/16] cargo fmt

---
 embassy-stm32/src/i2c/v2.rs | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 6627d7f67..093b960d8 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -749,7 +749,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     #[cfg(not(feature = "time"))]
-    pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> {
+    pub fn blocking_read_timeout(
+        &mut self,
+        address: u8,
+        read: &mut [u8],
+        check_timeout: impl Fn() -> Result<(), Error>,
+    ) -> Result<(), Error> {
         self.read_internal(address, read, false, check_timeout)
         // Automatic Stop
     }
@@ -768,7 +773,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
     }
 
     #[cfg(not(feature = "time"))]
-    pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> {
+    pub fn blocking_write_timeout(
+        &mut self,
+        address: u8,
+        write: &[u8],
+        check_timeout: impl Fn() -> Result<(), Error>,
+    ) -> Result<(), Error> {
         self.write_internal(address, write, true, check_timeout)
     }
 

From f76d50e837cab098cd255c15ee0655c8d3ffb55b Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:39:24 +0200
Subject: [PATCH 10/16] cfg! macro didn't work, had to duplicate functions with
 different guards

---
 embassy-stm32/src/i2c/v2.rs | 50 +++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 093b960d8..926a3f7a1 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -7,6 +7,7 @@ use embassy_embedded_hal::SetConfig;
 use embassy_hal_internal::drop::OnDrop;
 use embassy_hal_internal::{into_ref, PeripheralRef};
 use embassy_sync::waitqueue::AtomicWaker;
+#[cfg(feature = "time")]
 use embassy_time::{Duration, Instant};
 
 use crate::dma::{NoDma, Transfer};
@@ -759,12 +760,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         // Automatic Stop
     }
 
+    #[cfg(feature = "time")]
     pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
-        if cfg!(feature = "time") {
-            self.blocking_read_timeout(address, read, self.timeout)
-        } else {
-            self.blocking_read_timeout(address, read, || Ok(()))
-        }
+        self.blocking_read_timeout(address, read, self.timeout)
+    }
+
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
+        self.blocking_read_timeout(address, read, || Ok(()))
     }
 
     #[cfg(feature = "time")]
@@ -782,12 +785,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.write_internal(address, write, true, check_timeout)
     }
 
+    #[cfg(feature = "time")]
     pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
-        if cfg!(feature = "time") {
-            self.blocking_write_timeout(address, write, self.timeout)
-        } else {
-            self.blocking_write_timeout(address, write, || Ok(()))
-        }
+        self.blocking_write_timeout(address, write, self.timeout)
+    }
+
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
+        self.blocking_write_timeout(address, write, || Ok(()))
     }
 
     #[cfg(feature = "time")]
@@ -812,18 +817,19 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         read: &mut [u8],
         check_timeout: impl Fn() -> Result<(), Error>,
     ) -> Result<(), Error> {
-        let check_timeout = timeout_fn(timeout);
         self.write_internal(address, write, false, &check_timeout)?;
         self.read_internal(address, read, true, &check_timeout)
         // Automatic Stop
     }
 
+    #[cfg(feature = "time")]
     pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        if cfg!(feature = "time") {
-            self.blocking_write_read_timeout(address, write, read, self.timeout)
-        } else {
-            self.blocking_write_read_timeout(address, write, read, || Ok(()))
-        }
+        self.blocking_write_read_timeout(address, write, read, self.timeout)
+    }
+
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
+        self.blocking_write_read_timeout(address, write, read, || Ok(()))
     }
 
     fn blocking_write_vectored_with_timeout(
@@ -925,12 +931,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         self.blocking_write_vectored_with_timeout(address, write, check_timeout)
     }
 
+    #[cfg(feature = "time")]
     pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
-        if cfg!(feature = "time") {
-            self.blocking_write_vectored_timeout(address, write, self.timeout)
-        } else {
-            self.blocking_write_vectored_timeout(address, write, || Ok(()))
-        }
+        self.blocking_write_vectored_timeout(address, write, self.timeout)
+    }
+
+    #[cfg(not(feature = "time"))]
+    pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
+        self.blocking_write_vectored_timeout(address, write, || Ok(()))
     }
 }
 

From 032b1f2d5976422b12e5cb023de939e5a1cd0c37 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:42:40 +0200
Subject: [PATCH 11/16] Fix some issues with unused stuff

---
 embassy-stm32/src/i2c/v2.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 926a3f7a1..8a7fa6a9f 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -74,6 +74,7 @@ impl State {
 
 pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
     _peri: PeripheralRef<'d, T>,
+    #[allow(dead_code)]
     tx_dma: PeripheralRef<'d, TXDMA>,
     #[allow(dead_code)]
     rx_dma: PeripheralRef<'d, RXDMA>,
@@ -432,6 +433,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         result
     }
 
+    #[cfg(feature = "time")]
     async fn write_dma_internal(
         &mut self,
         address: u8,
@@ -522,6 +524,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
         Ok(())
     }
 
+    #[cfg(feature = "time")]
     async fn read_dma_internal(
         &mut self,
         address: u8,

From 2f7c2750d1ec1f741c5c7900a73aca392abecaa3 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:45:47 +0200
Subject: [PATCH 12/16] Feature guarded more unused stuff

---
 embassy-stm32/src/i2c/v2.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 8a7fa6a9f..291ac13fd 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -1,16 +1,22 @@
 use core::cmp;
+#[cfg(feature = "time")]
 use core::future::poll_fn;
 use core::marker::PhantomData;
+#[cfg(feature = "time")]
 use core::task::Poll;
 
 use embassy_embedded_hal::SetConfig;
+#[cfg(feature = "time")]
 use embassy_hal_internal::drop::OnDrop;
 use embassy_hal_internal::{into_ref, PeripheralRef};
 use embassy_sync::waitqueue::AtomicWaker;
 #[cfg(feature = "time")]
 use embassy_time::{Duration, Instant};
 
-use crate::dma::{NoDma, Transfer};
+use crate::dma::NoDma;
+#[cfg(feature = "time")]
+use crate::dma::Transfer;
+
 use crate::gpio::sealed::AFType;
 use crate::gpio::Pull;
 use crate::i2c::{Error, Instance, SclPin, SdaPin};

From e6c47c371823b61124276da9677f1aa1d4b2a2f7 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:47:24 +0200
Subject: [PATCH 13/16] cargo fmt

---
 embassy-stm32/src/i2c/v2.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 291ac13fd..41aa0b6d0 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -16,7 +16,6 @@ use embassy_time::{Duration, Instant};
 use crate::dma::NoDma;
 #[cfg(feature = "time")]
 use crate::dma::Transfer;
-
 use crate::gpio::sealed::AFType;
 use crate::gpio::Pull;
 use crate::i2c::{Error, Instance, SclPin, SdaPin};

From 4cec4b0548b6782e350bbea0579cdfb6f40d6623 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:52:26 +0200
Subject: [PATCH 14/16] Remove more unused stuff

---
 examples/stm32f4/src/bin/i2c.rs | 1 -
 examples/stm32h5/src/bin/i2c.rs | 1 -
 examples/stm32h7/src/bin/i2c.rs | 1 -
 3 files changed, 3 deletions(-)

diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs
index 10ca2bdc7..032bd97ee 100644
--- a/examples/stm32f4/src/bin/i2c.rs
+++ b/examples/stm32f4/src/bin/i2c.rs
@@ -8,7 +8,6 @@ use embassy_stm32::dma::NoDma;
 use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
-use embassy_time::Duration;
 use {defmt_rtt as _, panic_probe as _};
 
 const ADDRESS: u8 = 0x5F;
diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs
index 4ce378e9b..8b1662f39 100644
--- a/examples/stm32h5/src/bin/i2c.rs
+++ b/examples/stm32h5/src/bin/i2c.rs
@@ -7,7 +7,6 @@ use embassy_executor::Spawner;
 use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
-use embassy_time::Duration;
 use {defmt_rtt as _, panic_probe as _};
 
 const ADDRESS: u8 = 0x5F;
diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs
index 7cd12e5eb..9aa0ca08b 100644
--- a/examples/stm32h7/src/bin/i2c.rs
+++ b/examples/stm32h7/src/bin/i2c.rs
@@ -7,7 +7,6 @@ use embassy_executor::Spawner;
 use embassy_stm32::i2c::{Error, I2c};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::{bind_interrupts, i2c, peripherals};
-use embassy_time::Duration;
 use {defmt_rtt as _, panic_probe as _};
 
 const ADDRESS: u8 = 0x5F;

From 063e6f96daecf8f68a538c0f1904619d84333926 Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Wed, 11 Oct 2023 23:56:21 +0200
Subject: [PATCH 15/16] Remove outdated comment

---
 embassy-stm32/src/i2c/mod.rs | 2 --
 1 file changed, 2 deletions(-)

diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 204ad679d..dde1a5040 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -2,8 +2,6 @@
 
 use crate::interrupt;
 
-// I2C V2 is gated on the `time` feature because timing facilities are necessary
-// to provide timeout functionality in order to prevent some APIs from stalling indefinitely
 #[cfg_attr(i2c_v1, path = "v1.rs")]
 #[cfg_attr(i2c_v2, path = "v2.rs")]
 mod _version;

From f0d6ee69bcac6a22213c06f303176daf9f5445ff Mon Sep 17 00:00:00 2001
From: Andres Oliva <andres.oliva@teufel.de>
Date: Thu, 12 Oct 2023 11:25:44 +0200
Subject: [PATCH 16/16] Add some builds without time feature to CI

---
 ci.sh        | 6 ++++++
 ci_stable.sh | 5 +++++
 2 files changed, 11 insertions(+)

diff --git a/ci.sh b/ci.sh
index 4098743f4..c246e6a98 100755
--- a/ci.sh
+++ b/ci.sh
@@ -83,6 +83,12 @@ cargo batch  \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \
diff --git a/ci_stable.sh b/ci_stable.sh
index 61b02175f..1fe4e3a1e 100755
--- a/ci_stable.sh
+++ b/ci_stable.sh
@@ -35,6 +35,11 @@ cargo batch  \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \