Skip to content

Commit bb1ad14

Browse files
authored
I2C: Make non-async fn available in async-mode (#3056)
* I2C: Make non-async fn available in async-mode * PR number
1 parent 2ff28b1 commit bb1ad14

File tree

4 files changed

+113
-100
lines changed

4 files changed

+113
-100
lines changed

esp-hal/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131

3232
- Removed features `psram-quad` and `psram-octal` - replaced by `psram` and the `ESP_HAL_CONFIG_PSRAM_MODE` (`quad`/`octal`) (#3001)
3333

34+
- I2C: Async functions are postfixed with `_async`, non-async functions are available in async-mode (#3056)
35+
3436
### Fixed
3537

3638
- `DmaDescriptor` is now `#[repr(C)]` (#2988)

esp-hal/MIGRATING-0.23.md

+9
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,12 @@ The OutputOpenDrain driver has been removed. You can use `Output` instead with
200200
.with_drive_mode(DriveMode::OpenDrain),
201201
);
202202
```
203+
204+
## I2C Changes
205+
206+
All async functions now include the `_async` postfix. Additionally the non-async functions are now available in async-mode.
207+
208+
```diff
209+
- let result = i2c.write_read(0x77, &[0xaa], &mut data).await;
210+
+ let result = i2c.write_read_async(0x77, &[0xaa], &mut data).await;
211+
```

esp-hal/src/i2c/master/mod.rs

+99-99
Original file line numberDiff line numberDiff line change
@@ -596,101 +596,6 @@ impl<'d, Dm: DriverMode> I2c<'d, Dm> {
596596

597597
*guard = OutputConnection::connect_with_guard(pin, output);
598598
}
599-
}
600-
601-
impl<'d> I2c<'d, Blocking> {
602-
/// Create a new I2C instance.
603-
///
604-
/// # Errors
605-
///
606-
/// A [`ConfigError`] variant will be returned if bus frequency or timeout
607-
/// passed in config is invalid.
608-
pub fn new(
609-
i2c: impl Peripheral<P = impl Instance> + 'd,
610-
config: Config,
611-
) -> Result<Self, ConfigError> {
612-
crate::into_mapped_ref!(i2c);
613-
614-
let guard = PeripheralGuard::new(i2c.info().peripheral);
615-
616-
let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
617-
let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
618-
619-
let i2c = I2c {
620-
i2c,
621-
phantom: PhantomData,
622-
config,
623-
guard,
624-
sda_pin,
625-
scl_pin,
626-
};
627-
628-
i2c.driver().setup(&i2c.config)?;
629-
630-
Ok(i2c)
631-
}
632-
633-
#[cfg_attr(
634-
not(multi_core),
635-
doc = "Registers an interrupt handler for the peripheral."
636-
)]
637-
#[cfg_attr(
638-
multi_core,
639-
doc = "Registers an interrupt handler for the peripheral on the current core."
640-
)]
641-
#[doc = ""]
642-
/// Note that this will replace any previously registered interrupt
643-
/// handlers.
644-
///
645-
/// You can restore the default/unhandled interrupt handler by using
646-
/// [crate::DEFAULT_INTERRUPT_HANDLER]
647-
///
648-
/// # Panics
649-
///
650-
/// Panics if passed interrupt handler is invalid (e.g. has priority
651-
/// `None`)
652-
#[instability::unstable]
653-
pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
654-
self.i2c.info().set_interrupt_handler(handler);
655-
}
656-
657-
/// Listen for the given interrupts
658-
#[instability::unstable]
659-
pub fn listen(&mut self, interrupts: impl Into<EnumSet<Event>>) {
660-
self.i2c.info().enable_listen(interrupts.into(), true)
661-
}
662-
663-
/// Unlisten the given interrupts
664-
#[instability::unstable]
665-
pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
666-
self.i2c.info().enable_listen(interrupts.into(), false)
667-
}
668-
669-
/// Gets asserted interrupts
670-
#[instability::unstable]
671-
pub fn interrupts(&mut self) -> EnumSet<Event> {
672-
self.i2c.info().interrupts()
673-
}
674-
675-
/// Resets asserted interrupts
676-
#[instability::unstable]
677-
pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
678-
self.i2c.info().clear_interrupts(interrupts)
679-
}
680-
681-
/// Configures the I2C peripheral to operate in asynchronous mode.
682-
pub fn into_async(mut self) -> I2c<'d, Async> {
683-
self.set_interrupt_handler(self.driver().info.async_handler);
684-
685-
I2c {
686-
i2c: self.i2c,
687-
phantom: PhantomData,
688-
config: self.config,
689-
guard: self.guard,
690-
sda_pin: self.sda_pin,
691-
scl_pin: self.scl_pin,
692-
}
693-
}
694599

695600
/// Writes bytes to slave with address `address`
696601
/// ```rust, no_run
@@ -826,6 +731,101 @@ impl<'d> I2c<'d, Blocking> {
826731
}
827732
}
828733

734+
impl<'d> I2c<'d, Blocking> {
735+
/// Create a new I2C instance.
736+
///
737+
/// # Errors
738+
///
739+
/// A [`ConfigError`] variant will be returned if bus frequency or timeout
740+
/// passed in config is invalid.
741+
pub fn new(
742+
i2c: impl Peripheral<P = impl Instance> + 'd,
743+
config: Config,
744+
) -> Result<Self, ConfigError> {
745+
crate::into_mapped_ref!(i2c);
746+
747+
let guard = PeripheralGuard::new(i2c.info().peripheral);
748+
749+
let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
750+
let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
751+
752+
let i2c = I2c {
753+
i2c,
754+
phantom: PhantomData,
755+
config,
756+
guard,
757+
sda_pin,
758+
scl_pin,
759+
};
760+
761+
i2c.driver().setup(&i2c.config)?;
762+
763+
Ok(i2c)
764+
}
765+
766+
#[cfg_attr(
767+
not(multi_core),
768+
doc = "Registers an interrupt handler for the peripheral."
769+
)]
770+
#[cfg_attr(
771+
multi_core,
772+
doc = "Registers an interrupt handler for the peripheral on the current core."
773+
)]
774+
#[doc = ""]
775+
/// Note that this will replace any previously registered interrupt
776+
/// handlers.
777+
///
778+
/// You can restore the default/unhandled interrupt handler by using
779+
/// [crate::DEFAULT_INTERRUPT_HANDLER]
780+
///
781+
/// # Panics
782+
///
783+
/// Panics if passed interrupt handler is invalid (e.g. has priority
784+
/// `None`)
785+
#[instability::unstable]
786+
pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
787+
self.i2c.info().set_interrupt_handler(handler);
788+
}
789+
790+
/// Listen for the given interrupts
791+
#[instability::unstable]
792+
pub fn listen(&mut self, interrupts: impl Into<EnumSet<Event>>) {
793+
self.i2c.info().enable_listen(interrupts.into(), true)
794+
}
795+
796+
/// Unlisten the given interrupts
797+
#[instability::unstable]
798+
pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
799+
self.i2c.info().enable_listen(interrupts.into(), false)
800+
}
801+
802+
/// Gets asserted interrupts
803+
#[instability::unstable]
804+
pub fn interrupts(&mut self) -> EnumSet<Event> {
805+
self.i2c.info().interrupts()
806+
}
807+
808+
/// Resets asserted interrupts
809+
#[instability::unstable]
810+
pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
811+
self.i2c.info().clear_interrupts(interrupts)
812+
}
813+
814+
/// Configures the I2C peripheral to operate in asynchronous mode.
815+
pub fn into_async(mut self) -> I2c<'d, Async> {
816+
self.set_interrupt_handler(self.driver().info.async_handler);
817+
818+
I2c {
819+
i2c: self.i2c,
820+
phantom: PhantomData,
821+
config: self.config,
822+
guard: self.guard,
823+
sda_pin: self.sda_pin,
824+
scl_pin: self.scl_pin,
825+
}
826+
}
827+
}
828+
829829
impl private::Sealed for I2c<'_, Blocking> {}
830830

831831
impl InterruptConfigurable for I2c<'_, Blocking> {
@@ -959,7 +959,7 @@ impl<'d> I2c<'d, Async> {
959959
}
960960

961961
/// Writes bytes to slave with address `address`
962-
pub async fn write<A: Into<I2cAddress>>(
962+
pub async fn write_async<A: Into<I2cAddress>>(
963963
&mut self,
964964
address: A,
965965
buffer: &[u8],
@@ -976,7 +976,7 @@ impl<'d> I2c<'d, Async> {
976976
///
977977
/// The corresponding error variant from [`Error`] will be returned if the
978978
/// passed buffer has zero length.
979-
pub async fn read<A: Into<I2cAddress>>(
979+
pub async fn read_async<A: Into<I2cAddress>>(
980980
&mut self,
981981
address: A,
982982
buffer: &mut [u8],
@@ -994,7 +994,7 @@ impl<'d> I2c<'d, Async> {
994994
///
995995
/// The corresponding error variant from [`Error`] will be returned if the
996996
/// passed buffer has zero length.
997-
pub async fn write_read<A: Into<I2cAddress>>(
997+
pub async fn write_read_async<A: Into<I2cAddress>>(
998998
&mut self,
999999
address: A,
10001000
write_buffer: &[u8],
@@ -1039,7 +1039,7 @@ impl<'d> I2c<'d, Async> {
10391039
///
10401040
/// The corresponding error variant from [`Error`] will be returned if the
10411041
/// buffer passed to an [`Operation`] has zero length.
1042-
pub async fn transaction<'a, A: Into<I2cAddress>>(
1042+
pub async fn transaction_async<'a, A: Into<I2cAddress>>(
10431043
&mut self,
10441044
address: A,
10451045
operations: impl IntoIterator<Item = &'a mut Operation<'a>>,

qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ async fn main(_spawner: Spawner) {
4444

4545
loop {
4646
let mut data = [0u8; 22];
47-
i2c.write_read(0x77, &[0xaa], &mut data).await.unwrap();
47+
i2c.write_read_async(0x77, &[0xaa], &mut data)
48+
.await
49+
.unwrap();
4850
esp_println::println!("direct: {:02x?}", data);
4951
read_data(&mut i2c).await;
5052
Timer::after(Duration::from_millis(1000)).await;

0 commit comments

Comments
 (0)