diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 6fa269fc..6b2c8a35 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -3,9 +3,6 @@ use crate::time::Hertz; use core::marker::PhantomData; use embassy::util::Unborrow; use embassy_hal_common::unborrow; -use embedded_hal::blocking::i2c::Read; -use embedded_hal::blocking::i2c::Write; -use embedded_hal::blocking::i2c::WriteRead; use crate::pac::i2c; @@ -179,12 +176,8 @@ impl<'d, T: Instance> I2c<'d, T> { let value = T::regs().dr().read().dr(); Ok(value) } -} -impl<'d, T: Instance> Read for I2c<'d, T> { - type Error = Error; - - fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + pub fn blocking_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> { if let Some((last, buffer)) = buffer.split_last_mut() { // Send a START condition and set ACK bit unsafe { @@ -248,12 +241,8 @@ impl<'d, T: Instance> Read for I2c<'d, T> { Err(Error::Overrun) } } -} -impl<'d, T: Instance> Write for I2c<'d, T> { - type Error = Error; - - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { + pub fn blocking_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { unsafe { self.write_bytes(addr, bytes)?; // Send a STOP condition @@ -267,16 +256,41 @@ impl<'d, T: Instance> Write for I2c<'d, T> { // Fallthrough is success Ok(()) } + + pub fn blocking_write_read( + &mut self, + addr: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Error> { + unsafe { self.write_bytes(addr, bytes)? }; + self.blocking_read(addr, buffer)?; + + Ok(()) + } } -impl<'d, T: Instance> WriteRead for I2c<'d, T> { +impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { + type Error = Error; + + fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.blocking_read(addr, buffer) + } +} + +impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { + type Error = Error; + + fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.blocking_write(addr, bytes) + } +} + +impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { type Error = Error; fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { - unsafe { self.write_bytes(addr, bytes)? }; - self.read(addr, buffer)?; - - Ok(()) + self.blocking_write_read(addr, bytes, buffer) } } diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 73b6f551..af04dc06 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -10,9 +10,6 @@ use embassy::util::Unborrow; use embassy::waitqueue::AtomicWaker; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::unborrow; -use embedded_hal::blocking::i2c::Read; -use embedded_hal::blocking::i2c::Write; -use embedded_hal::blocking::i2c::WriteRead; use futures::future::poll_fn; use crate::dma::NoDma; @@ -300,7 +297,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } - fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> { + fn read_internal( + &mut self, + address: u8, + buffer: &mut [u8], + restart: bool, + ) -> Result<(), Error> { let completed_chunks = buffer.len() / 255; let total_chunks = if completed_chunks * 255 == buffer.len() { completed_chunks @@ -339,7 +341,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> { + fn write_internal(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> { let completed_chunks = bytes.len() / 255; let total_chunks = if completed_chunks * 255 == bytes.len() { completed_chunks @@ -568,14 +570,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - pub async fn write_dma(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> + // ========================= + // Async public API + + pub async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { self.write_dma_internal(address, bytes, true, true).await } - pub async fn write_dma_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> + pub async fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { @@ -597,19 +602,52 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - pub async fn read_dma( - &mut self, - address: u8, - buffer: &mut [u8], - restart: bool, - ) -> Result<(), Error> + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, { - self.read_dma_internal(address, buffer, restart).await + self.read_dma_internal(address, buffer, false).await } - pub fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> { + pub async fn write_read( + &mut self, + address: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Error> + where + TXDMA: super::TxDma, + RXDMA: super::RxDma, + { + self.write_dma_internal(address, bytes, true, true).await?; + self.read_dma_internal(address, buffer, true).await?; + Ok(()) + } + + // ========================= + // Blocking public API + + pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { + self.read_internal(address, buffer, false) + // Automatic Stop + } + + pub fn blocking_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> { + self.write_internal(address, bytes, true) + } + + pub fn blocking_write_read( + &mut self, + address: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Error> { + self.write_internal(address, bytes, false)?; + self.read_internal(address, buffer, true) + // Automatic Stop + } + + pub fn blocking_write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> { if bytes.is_empty() { return Err(Error::ZeroLengthTransfer); } @@ -679,24 +717,23 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } -impl<'d, T: Instance> Read for I2c<'d, T> { +impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { type Error = Error; fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.read(address, buffer, false) - // Automatic Stop + self.blocking_read(address, buffer) } } -impl<'d, T: Instance> Write for I2c<'d, T> { +impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { type Error = Error; fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { - self.write(address, bytes, true) + self.blocking_write(address, bytes) } } -impl<'d, T: Instance> WriteRead for I2c<'d, T> { +impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { type Error = Error; fn write_read( @@ -705,9 +742,7 @@ impl<'d, T: Instance> WriteRead for I2c<'d, T> { bytes: &[u8], buffer: &mut [u8], ) -> Result<(), Self::Error> { - self.write(address, bytes, false)?; - self.read(address, buffer, true) - // Automatic Stop + self.blocking_write_read(address, bytes, buffer) } } @@ -715,7 +750,7 @@ impl<'d, T: Instance> WriteRead for I2c<'d, T> { /// /// Peripheral options for generating the STOP condition #[derive(Copy, Clone, PartialEq)] -pub enum Stop { +enum Stop { /// Software end mode: Must write register to generate STOP condition Software, /// Automatic end mode: A STOP condition is automatically generated once the @@ -860,32 +895,23 @@ impl<'d, T: Instance, TXDMA: super::TxDma, RXDMA: super::RxDma> I2cTrait where - 'd: 'a, - T: 'a, - TXDMA: 'a, - RXDMA: 'a, + Self: 'a, = impl Future> + 'a; type ReadFuture<'a> where - 'd: 'a, - T: 'a, - TXDMA: 'a, - RXDMA: 'a, + Self: 'a, = impl Future> + 'a; type WriteReadFuture<'a> where - 'd: 'a, - T: 'a, - TXDMA: 'a, - RXDMA: 'a, + Self: 'a, = impl Future> + 'a; fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read_dma(address, buffer, false) + self.read(address, buffer) } fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { - self.write_dma(address, bytes) + self.write(address, bytes) } fn write_read<'a>( @@ -894,9 +920,6 @@ impl<'d, T: Instance, TXDMA: super::TxDma, RXDMA: super::RxDma> I2cTrait Self::WriteReadFuture<'a> { - async move { - self.write_dma(address, bytes).await?; - self.read_dma(address, buffer, true).await - } + self.write_read(address, bytes, buffer) } } diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index 86215697..615012a0 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs @@ -11,7 +11,6 @@ use embassy_stm32::i2c::I2c; use embassy_stm32::interrupt; use embassy_stm32::time::Hertz; use embassy_stm32::Peripherals; -use embedded_hal::blocking::i2c::WriteRead; use example_common::{info, unwrap}; const ADDRESS: u8 = 0x5F; @@ -23,6 +22,6 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! { let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000)); let mut data = [0u8; 1]; - unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data)); + unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); info!("Whoami: {}", data[0]); } diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs index b0596aab..d77bee8c 100644 --- a/examples/stm32l4/src/bin/i2c_dma.rs +++ b/examples/stm32l4/src/bin/i2c_dma.rs @@ -6,7 +6,6 @@ mod example_common; use embassy::executor::Spawner; -use embassy::traits::i2c::I2c as I2cTrait; use embassy_stm32::i2c::I2c; use embassy_stm32::interrupt; use embassy_stm32::time::Hertz;