From ec2ab822b8fa23c1758bf40bd7ac276bfb1ab543 Mon Sep 17 00:00:00 2001 From: dragonn Date: Fri, 27 Dec 2024 21:18:59 +0100 Subject: [PATCH 1/4] nrf twim return errors in async_wait --- embassy-nrf/src/twim.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index ebad39df2..df1de83a2 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -85,6 +85,8 @@ pub enum Error { Overrun, /// Timeout error. Timeout, + /// Bus error. + Bus, } /// Interrupt handler. @@ -329,7 +331,7 @@ impl<'d, T: Instance> Twim<'d, T> { } /// Wait for stop or error - fn async_wait(&mut self) -> impl Future { + fn async_wait(&mut self) -> impl Future> { poll_fn(move |cx| { let r = T::regs(); let s = T::state(); @@ -338,13 +340,23 @@ impl<'d, T: Instance> Twim<'d, T> { if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { r.events_stopped().write_value(0); - return Poll::Ready(()); + return Poll::Ready(Ok(())); } // stop if an error occurred if r.events_error().read() != 0 { r.events_error().write_value(0); r.tasks_stop().write_value(1); + let errorsrc = r.errorsrc().read(); + if errorsrc.overrun() { + return Poll::Ready(Err(Error::Overrun)); + } else if errorsrc.anack() { + return Poll::Ready(Err(Error::AddressNack)); + } else if errorsrc.dnack() { + return Poll::Ready(Err(Error::DataNack)); + } else { + return Poll::Ready(Err(Error::Bus)); + } } Poll::Pending @@ -626,7 +638,7 @@ impl<'d, T: Instance> Twim<'d, T> { while !operations.is_empty() { let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, true)?; let (in_progress, rest) = operations.split_at_mut(ops); - self.async_wait().await; + self.async_wait().await?; self.check_operations(in_progress)?; last_op = in_progress.last(); operations = rest; @@ -644,7 +656,7 @@ impl<'d, T: Instance> Twim<'d, T> { while !operations.is_empty() { let ops = self.setup_operations(address, operations, None, last_op, true)?; let (in_progress, rest) = operations.split_at_mut(ops); - self.async_wait().await; + self.async_wait().await?; self.check_operations(in_progress)?; last_op = in_progress.last(); operations = rest; @@ -910,6 +922,7 @@ impl embedded_hal_1::i2c::Error for Error { } Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun, Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other, + Self::Bus => embedded_hal_1::i2c::ErrorKind::Other, } } } From 0316ef86cbda80f3f724b126c4e7860571b91d8a Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 8 Jan 2025 14:19:25 +0100 Subject: [PATCH 2/4] use check_errorsrc instead of matching again on errorsrc bits --- embassy-nrf/src/twim.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index df1de83a2..687f53311 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -347,13 +347,8 @@ impl<'d, T: Instance> Twim<'d, T> { if r.events_error().read() != 0 { r.events_error().write_value(0); r.tasks_stop().write_value(1); - let errorsrc = r.errorsrc().read(); - if errorsrc.overrun() { - return Poll::Ready(Err(Error::Overrun)); - } else if errorsrc.anack() { - return Poll::Ready(Err(Error::AddressNack)); - } else if errorsrc.dnack() { - return Poll::Ready(Err(Error::DataNack)); + if let Err(e) = self.check_errorsrc() { + return Poll::Ready(Err(e)); } else { return Poll::Ready(Err(Error::Bus)); } From 5102b50be71888364dff366d650b406d7ae1f50e Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 8 Jan 2025 14:55:37 +0100 Subject: [PATCH 3/4] remove self from check_errorsrc to make it work in async_wait --- embassy-nrf/src/twim.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 687f53311..708a69082 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -257,7 +257,7 @@ impl<'d, T: Instance> Twim<'d, T> { } /// Get Error instance, if any occurred. - fn check_errorsrc(&self) -> Result<(), Error> { + fn check_errorsrc() -> Result<(), Error> { let r = T::regs(); let err = r.errorsrc().read(); @@ -347,7 +347,7 @@ impl<'d, T: Instance> Twim<'d, T> { if r.events_error().read() != 0 { r.events_error().write_value(0); r.tasks_stop().write_value(1); - if let Err(e) = self.check_errorsrc() { + if let Err(e) = Self::check_errorsrc() { return Poll::Ready(Err(e)); } else { return Poll::Ready(Err(Error::Bus)); @@ -510,7 +510,7 @@ impl<'d, T: Instance> Twim<'d, T> { fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> { compiler_fence(SeqCst); - self.check_errorsrc()?; + Self::check_errorsrc()?; assert!(operations.len() == 1 || operations.len() == 2); match operations { From cd38669ac2239c484e181bbcc8e4804e9de28039 Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 8 Jan 2025 19:08:58 +0100 Subject: [PATCH 4/4] panic when events_error is set in twim without errorsrc --- embassy-nrf/src/twim.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 708a69082..bfce00f1b 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -85,8 +85,6 @@ pub enum Error { Overrun, /// Timeout error. Timeout, - /// Bus error. - Bus, } /// Interrupt handler. @@ -350,7 +348,7 @@ impl<'d, T: Instance> Twim<'d, T> { if let Err(e) = Self::check_errorsrc() { return Poll::Ready(Err(e)); } else { - return Poll::Ready(Err(Error::Bus)); + panic!("Found events_error bit without an error in errorsrc reg"); } } @@ -917,7 +915,6 @@ impl embedded_hal_1::i2c::Error for Error { } Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun, Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other, - Self::Bus => embedded_hal_1::i2c::ErrorKind::Other, } } }