From 43c1afb6a6b31a60f43b2faf8ca93bf5129e4d68 Mon Sep 17 00:00:00 2001 From: kalkyl <henrik.alser@me.com> Date: Mon, 14 Nov 2022 11:22:14 +0100 Subject: [PATCH] Return number of bytes written, add address match getter --- embassy-nrf/src/twis.rs | 141 +++++++++++++++++++---------------- examples/nrf/src/bin/twis.rs | 2 +- 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index 8c9cb54ea..769522877 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs @@ -24,8 +24,8 @@ use crate::{gpio, pac, Peripheral}; #[non_exhaustive] pub struct Config { - pub addr0: u8, - pub addr1: Option<u8>, + pub address0: u8, + pub address1: Option<u8>, pub orc: u8, pub sda_high_drive: bool, pub sda_pullup: bool, @@ -36,8 +36,8 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { - addr0: 0x55, - addr1: None, + address0: 0x55, + address1: None, orc: 0x00, scl_high_drive: false, sda_pullup: false, @@ -134,10 +134,10 @@ impl<'d, T: Instance> Twis<'d, T> { r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // Set address - r.address[0].write(|w| unsafe { w.address().bits(config.addr0) }); + r.address[0].write(|w| unsafe { w.address().bits(config.address0) }); r.config.modify(|_r, w| w.address0().enabled()); - if let Some(addr1) = config.addr1 { - r.address[1].write(|w| unsafe { w.address().bits(addr1) }); + if let Some(address1) = config.address1 { + r.address[1].write(|w| unsafe { w.address().bits(address1) }); r.config.modify(|_r, w| w.address1().enabled()); } @@ -242,7 +242,13 @@ impl<'d, T: Instance> Twis<'d, T> { .write(|w| w.overflow().bit(true).overread().bit(true).dnack().bit(true)); } - /// Wait for stop or error + /// Returns matched address for latest command. + pub fn address_match(&self) -> u8 { + let r = T::regs(); + r.address[r.match_.read().bits() as usize].read().address().bits() + } + + /// Wait for read, write, stop or error fn blocking_listen_wait(&mut self) -> Result<Status, Error> { let r = T::regs(); loop { @@ -267,7 +273,7 @@ impl<'d, T: Instance> Twis<'d, T> { } } - /// Wait for stop or error + /// Wait for stop, repeated start or error fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> { let r = T::regs(); loop { @@ -294,7 +300,7 @@ impl<'d, T: Instance> Twis<'d, T> { } /// Wait for stop or error - fn blocking_wait(&mut self) -> Result<(), Error> { + fn blocking_wait(&mut self) -> Result<usize, Error> { let r = T::regs(); loop { // stop if an error occured @@ -311,12 +317,42 @@ impl<'d, T: Instance> Twis<'d, T> { } } else if r.events_stopped.read().bits() != 0 { r.events_stopped.reset(); - return Ok(()); + let n = r.txd.amount.read().bits() as usize; + return Ok(n); } } } - /// Wait for stop or error + /// Wait for stop or error with timeout + #[cfg(feature = "time")] + fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> { + let r = T::regs(); + let deadline = Instant::now() + timeout; + loop { + // stop if an error occured + if r.events_error.read().bits() != 0 { + r.events_error.reset(); + r.tasks_stop.write(|w| unsafe { w.bits(1) }); + let errorsrc = r.errorsrc.read(); + if errorsrc.overread().is_detected() { + return Err(Error::OverRead); + } else if errorsrc.dnack().is_received() { + return Err(Error::DataNack); + } else { + return Err(Error::Bus); + } + } else if r.events_stopped.read().bits() != 0 { + r.events_stopped.reset(); + let n = r.txd.amount.read().bits() as usize; + return Ok(n); + } else if Instant::now() > deadline { + r.tasks_stop.write(|w| unsafe { w.bits(1) }); + return Err(Error::Timeout); + } + } + } + + /// Wait for read, write, stop or error with timeout #[cfg(feature = "time")] fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> { let r = T::regs(); @@ -347,7 +383,7 @@ impl<'d, T: Instance> Twis<'d, T> { } } - /// Wait for stop or error + /// Wait for stop, repeated start or error with timeout #[cfg(feature = "time")] fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> { let r = T::regs(); @@ -379,35 +415,7 @@ impl<'d, T: Instance> Twis<'d, T> { } /// Wait for stop or error - #[cfg(feature = "time")] - fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> { - let r = T::regs(); - let deadline = Instant::now() + timeout; - loop { - // stop if an error occured - if r.events_error.read().bits() != 0 { - r.events_error.reset(); - r.tasks_stop.write(|w| unsafe { w.bits(1) }); - let errorsrc = r.errorsrc.read(); - if errorsrc.overread().is_detected() { - return Err(Error::OverRead); - } else if errorsrc.dnack().is_received() { - return Err(Error::DataNack); - } else { - return Err(Error::Bus); - } - } else if r.events_stopped.read().bits() != 0 { - r.events_stopped.reset(); - return Ok(()); - } else if Instant::now() > deadline { - r.tasks_stop.write(|w| unsafe { w.bits(1) }); - return Err(Error::Timeout); - } - } - } - - /// Wait for stop or error - fn async_wait(&mut self) -> impl Future<Output = Result<(), Error>> { + fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> { poll_fn(move |cx| { let r = T::regs(); let s = T::state(); @@ -428,7 +436,8 @@ impl<'d, T: Instance> Twis<'d, T> { } } else if r.events_stopped.read().bits() != 0 { r.events_stopped.reset(); - return Poll::Ready(Ok(())); + let n = r.txd.amount.read().bits() as usize; + return Poll::Ready(Ok(n)); } Poll::Pending @@ -462,7 +471,7 @@ impl<'d, T: Instance> Twis<'d, T> { }) } - /// Wait for stop or error + /// Wait for stop, repeated start or error fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> { poll_fn(move |cx| { let r = T::regs(); @@ -595,25 +604,23 @@ impl<'d, T: Instance> Twis<'d, T> { } /// Write to an I2C master. - /// + /// Returns the number of bytes written. /// The buffer must have a length of at most 255 bytes on the nRF52832 /// and at most 65535 bytes on the nRF52840. - pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { + pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> { self.setup_write(buffer, false)?; - self.blocking_wait()?; - Ok(()) + self.blocking_wait() } /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. - pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { + pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> { self.setup_write_from_ram(buffer, false)?; - self.blocking_wait()?; - Ok(()) + self.blocking_wait() } // =========================================== - /// Listen for commands from an I2C master. + /// Listen for commands from an I2C master with timeout. /// /// The buffer must have a length of at most 255 bytes on the nRF52832 /// and at most 65535 bytes on the nRF52840. @@ -630,25 +637,27 @@ impl<'d, T: Instance> Twis<'d, T> { } /// Write to an I2C master with timeout. - /// + /// Returns the number of bytes written. /// See [`blocking_write`]. #[cfg(feature = "time")] - pub fn blocking_write_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<(), Error> { + pub fn blocking_write_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> { self.setup_write(buffer, false)?; - self.blocking_wait_timeout(timeout)?; - Ok(()) + self.blocking_wait_timeout(timeout) } /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. #[cfg(feature = "time")] - pub fn blocking_write_from_ram_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<(), Error> { + pub fn blocking_write_from_ram_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> { self.setup_write_from_ram(buffer, false)?; - self.blocking_wait_timeout(timeout)?; - Ok(()) + self.blocking_wait_timeout(timeout) } // =========================================== + /// Listen asynchronously for commands from an I2C master. + /// + /// The buffer must have a length of at most 255 bytes on the nRF52832 + /// and at most 65535 bytes on the nRF52840. pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> { self.setup_listen(buffer, true)?; let status = self.async_listen_wait().await?; @@ -660,17 +669,19 @@ impl<'d, T: Instance> Twis<'d, T> { Ok(Command::Read) } - pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { + /// Async write to an I2C master. + /// Returns the number of bytes written. + /// The buffer must have a length of at most 255 bytes on the nRF52832 + /// and at most 65535 bytes on the nRF52840. + pub async fn write(&mut self, buffer: &[u8]) -> Result<usize, Error> { self.setup_write(buffer, true)?; - self.async_wait().await?; - Ok(()) + self.async_wait().await } /// Same as [`write`](Twis::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. - pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { + pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> { self.setup_write_from_ram(buffer, true)?; - self.async_wait().await?; - Ok(()) + self.async_wait().await } } diff --git a/examples/nrf/src/bin/twis.rs b/examples/nrf/src/bin/twis.rs index f85173c08..a34bb2711 100644 --- a/examples/nrf/src/bin/twis.rs +++ b/examples/nrf/src/bin/twis.rs @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); let mut config = twis::Config::default(); // Set i2c address - config.addr0 = 0x55; + config.address0 = 0x55; let mut i2c = Twis::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); info!("Listening...");