mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
I2C: Make non-async fn available in async-mode (#3056)
* I2C: Make non-async fn available in async-mode * PR number
This commit is contained in:
parent
2ff28b14b5
commit
bb1ad1485a
@ -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)
|
||||
|
@ -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;
|
||||
```
|
||||
|
@ -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<P = impl Instance> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, ConfigError> {
|
||||
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<EnumSet<Event>>) {
|
||||
self.i2c.info().enable_listen(interrupts.into(), true)
|
||||
}
|
||||
|
||||
/// Unlisten the given interrupts
|
||||
#[instability::unstable]
|
||||
pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
|
||||
self.i2c.info().enable_listen(interrupts.into(), false)
|
||||
}
|
||||
|
||||
/// Gets asserted interrupts
|
||||
#[instability::unstable]
|
||||
pub fn interrupts(&mut self) -> EnumSet<Event> {
|
||||
self.i2c.info().interrupts()
|
||||
}
|
||||
|
||||
/// Resets asserted interrupts
|
||||
#[instability::unstable]
|
||||
pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
|
||||
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<P = impl Instance> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, ConfigError> {
|
||||
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<EnumSet<Event>>) {
|
||||
self.i2c.info().enable_listen(interrupts.into(), true)
|
||||
}
|
||||
|
||||
/// Unlisten the given interrupts
|
||||
#[instability::unstable]
|
||||
pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
|
||||
self.i2c.info().enable_listen(interrupts.into(), false)
|
||||
}
|
||||
|
||||
/// Gets asserted interrupts
|
||||
#[instability::unstable]
|
||||
pub fn interrupts(&mut self) -> EnumSet<Event> {
|
||||
self.i2c.info().interrupts()
|
||||
}
|
||||
|
||||
/// Resets asserted interrupts
|
||||
#[instability::unstable]
|
||||
pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
|
||||
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<A: Into<I2cAddress>>(
|
||||
pub async fn write_async<A: Into<I2cAddress>>(
|
||||
&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<A: Into<I2cAddress>>(
|
||||
pub async fn read_async<A: Into<I2cAddress>>(
|
||||
&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<A: Into<I2cAddress>>(
|
||||
pub async fn write_read_async<A: Into<I2cAddress>>(
|
||||
&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<I2cAddress>>(
|
||||
pub async fn transaction_async<'a, A: Into<I2cAddress>>(
|
||||
&mut self,
|
||||
address: A,
|
||||
operations: impl IntoIterator<Item = &'a mut Operation<'a>>,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user