diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md
index 211c4af44..a9b81dc36 100644
--- a/esp-hal/CHANGELOG.md
+++ b/esp-hal/CHANGELOG.md
@@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed features `psram-quad` and `psram-octal` - replaced by `psram` and the `ESP_HAL_CONFIG_PSRAM_MODE` (`quad`/`octal`) (#3001)
+- I2C: Async functions are postfixed with `_async`, non-async functions are available in async-mode (#3056)
+
### Fixed
- `DmaDescriptor` is now `#[repr(C)]` (#2988)
diff --git a/esp-hal/MIGRATING-0.23.md b/esp-hal/MIGRATING-0.23.md
index 97696bb9a..acf5f4df8 100644
--- a/esp-hal/MIGRATING-0.23.md
+++ b/esp-hal/MIGRATING-0.23.md
@@ -200,3 +200,12 @@ The OutputOpenDrain driver has been removed. You can use `Output` instead with
.with_drive_mode(DriveMode::OpenDrain),
);
```
+
+## I2C Changes
+
+All async functions now include the `_async` postfix. Additionally the non-async functions are now available in async-mode.
+
+```diff
+- let result = i2c.write_read(0x77, &[0xaa], &mut data).await;
++ let result = i2c.write_read_async(0x77, &[0xaa], &mut data).await;
+```
diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs
index a754c223e..1530817cb 100644
--- a/esp-hal/src/i2c/master/mod.rs
+++ b/esp-hal/src/i2c/master/mod.rs
@@ -596,101 +596,6 @@ impl<'d, Dm: DriverMode> I2c<'d, Dm> {
*guard = OutputConnection::connect_with_guard(pin, output);
}
-}
-
-impl<'d> I2c<'d, Blocking> {
- /// Create a new I2C instance.
- ///
- /// # Errors
- ///
- /// A [`ConfigError`] variant will be returned if bus frequency or timeout
- /// passed in config is invalid.
- pub fn new(
- i2c: impl Peripheral
+ 'd,
- config: Config,
- ) -> Result {
- crate::into_mapped_ref!(i2c);
-
- let guard = PeripheralGuard::new(i2c.info().peripheral);
-
- let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
- let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
-
- let i2c = I2c {
- i2c,
- phantom: PhantomData,
- config,
- guard,
- sda_pin,
- scl_pin,
- };
-
- i2c.driver().setup(&i2c.config)?;
-
- Ok(i2c)
- }
-
- #[cfg_attr(
- not(multi_core),
- doc = "Registers an interrupt handler for the peripheral."
- )]
- #[cfg_attr(
- multi_core,
- doc = "Registers an interrupt handler for the peripheral on the current core."
- )]
- #[doc = ""]
- /// Note that this will replace any previously registered interrupt
- /// handlers.
- ///
- /// You can restore the default/unhandled interrupt handler by using
- /// [crate::DEFAULT_INTERRUPT_HANDLER]
- ///
- /// # Panics
- ///
- /// Panics if passed interrupt handler is invalid (e.g. has priority
- /// `None`)
- #[instability::unstable]
- pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
- self.i2c.info().set_interrupt_handler(handler);
- }
-
- /// Listen for the given interrupts
- #[instability::unstable]
- pub fn listen(&mut self, interrupts: impl Into>) {
- self.i2c.info().enable_listen(interrupts.into(), true)
- }
-
- /// Unlisten the given interrupts
- #[instability::unstable]
- pub fn unlisten(&mut self, interrupts: impl Into>) {
- self.i2c.info().enable_listen(interrupts.into(), false)
- }
-
- /// Gets asserted interrupts
- #[instability::unstable]
- pub fn interrupts(&mut self) -> EnumSet {
- self.i2c.info().interrupts()
- }
-
- /// Resets asserted interrupts
- #[instability::unstable]
- pub fn clear_interrupts(&mut self, interrupts: EnumSet) {
- self.i2c.info().clear_interrupts(interrupts)
- }
-
- /// Configures the I2C peripheral to operate in asynchronous mode.
- pub fn into_async(mut self) -> I2c<'d, Async> {
- self.set_interrupt_handler(self.driver().info.async_handler);
-
- I2c {
- i2c: self.i2c,
- phantom: PhantomData,
- config: self.config,
- guard: self.guard,
- sda_pin: self.sda_pin,
- scl_pin: self.scl_pin,
- }
- }
/// Writes bytes to slave with address `address`
/// ```rust, no_run
@@ -826,6 +731,101 @@ impl<'d> I2c<'d, Blocking> {
}
}
+impl<'d> I2c<'d, Blocking> {
+ /// Create a new I2C instance.
+ ///
+ /// # Errors
+ ///
+ /// A [`ConfigError`] variant will be returned if bus frequency or timeout
+ /// passed in config is invalid.
+ pub fn new(
+ i2c: impl Peripheral + 'd,
+ config: Config,
+ ) -> Result {
+ crate::into_mapped_ref!(i2c);
+
+ let guard = PeripheralGuard::new(i2c.info().peripheral);
+
+ let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
+ let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
+
+ let i2c = I2c {
+ i2c,
+ phantom: PhantomData,
+ config,
+ guard,
+ sda_pin,
+ scl_pin,
+ };
+
+ i2c.driver().setup(&i2c.config)?;
+
+ Ok(i2c)
+ }
+
+ #[cfg_attr(
+ not(multi_core),
+ doc = "Registers an interrupt handler for the peripheral."
+ )]
+ #[cfg_attr(
+ multi_core,
+ doc = "Registers an interrupt handler for the peripheral on the current core."
+ )]
+ #[doc = ""]
+ /// Note that this will replace any previously registered interrupt
+ /// handlers.
+ ///
+ /// You can restore the default/unhandled interrupt handler by using
+ /// [crate::DEFAULT_INTERRUPT_HANDLER]
+ ///
+ /// # Panics
+ ///
+ /// Panics if passed interrupt handler is invalid (e.g. has priority
+ /// `None`)
+ #[instability::unstable]
+ pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
+ self.i2c.info().set_interrupt_handler(handler);
+ }
+
+ /// Listen for the given interrupts
+ #[instability::unstable]
+ pub fn listen(&mut self, interrupts: impl Into>) {
+ self.i2c.info().enable_listen(interrupts.into(), true)
+ }
+
+ /// Unlisten the given interrupts
+ #[instability::unstable]
+ pub fn unlisten(&mut self, interrupts: impl Into>) {
+ self.i2c.info().enable_listen(interrupts.into(), false)
+ }
+
+ /// Gets asserted interrupts
+ #[instability::unstable]
+ pub fn interrupts(&mut self) -> EnumSet {
+ self.i2c.info().interrupts()
+ }
+
+ /// Resets asserted interrupts
+ #[instability::unstable]
+ pub fn clear_interrupts(&mut self, interrupts: EnumSet) {
+ self.i2c.info().clear_interrupts(interrupts)
+ }
+
+ /// Configures the I2C peripheral to operate in asynchronous mode.
+ pub fn into_async(mut self) -> I2c<'d, Async> {
+ self.set_interrupt_handler(self.driver().info.async_handler);
+
+ I2c {
+ i2c: self.i2c,
+ phantom: PhantomData,
+ config: self.config,
+ guard: self.guard,
+ sda_pin: self.sda_pin,
+ scl_pin: self.scl_pin,
+ }
+ }
+}
+
impl private::Sealed for I2c<'_, Blocking> {}
impl InterruptConfigurable for I2c<'_, Blocking> {
@@ -959,7 +959,7 @@ impl<'d> I2c<'d, Async> {
}
/// Writes bytes to slave with address `address`
- pub async fn write>(
+ pub async fn write_async>(
&mut self,
address: A,
buffer: &[u8],
@@ -976,7 +976,7 @@ impl<'d> I2c<'d, Async> {
///
/// The corresponding error variant from [`Error`] will be returned if the
/// passed buffer has zero length.
- pub async fn read>(
+ pub async fn read_async>(
&mut self,
address: A,
buffer: &mut [u8],
@@ -994,7 +994,7 @@ impl<'d> I2c<'d, Async> {
///
/// The corresponding error variant from [`Error`] will be returned if the
/// passed buffer has zero length.
- pub async fn write_read>(
+ pub async fn write_read_async>(
&mut self,
address: A,
write_buffer: &[u8],
@@ -1039,7 +1039,7 @@ impl<'d> I2c<'d, Async> {
///
/// The corresponding error variant from [`Error`] will be returned if the
/// buffer passed to an [`Operation`] has zero length.
- pub async fn transaction<'a, A: Into>(
+ pub async fn transaction_async<'a, A: Into>(
&mut self,
address: A,
operations: impl IntoIterator- >,
diff --git a/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs b/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs
index 38870dd8b..181e5988e 100644
--- a/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs
+++ b/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs
@@ -44,7 +44,9 @@ async fn main(_spawner: Spawner) {
loop {
let mut data = [0u8; 22];
- i2c.write_read(0x77, &[0xaa], &mut data).await.unwrap();
+ i2c.write_read_async(0x77, &[0xaa], &mut data)
+ .await
+ .unwrap();
esp_println::println!("direct: {:02x?}", data);
read_data(&mut i2c).await;
Timer::after(Duration::from_millis(1000)).await;