aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Reinholdsen <[email protected]>2025-02-27 20:18:24 +0100
committerFredrik Reinholdsen <[email protected]>2025-04-01 21:28:07 +0200
commit47869d122ab68ea9a962ba749c523b94066d0763 (patch)
treeafcb217b741fb4cc8eef31c602b55b3155e8dd9e
parenta44abaf7e4562fa5393087fd845bf0d02141325b (diff)
fix: Fix for #3888 async I2C read bug for introduced in #3887 in STM32 I2C v2 driver
In fixing a different timing related bug, #3887, a new bug was introduced causing I2C reads longer than 255 bytes to timeout for some I2C devices, #3888. The issue was caused by incorrect branch order, and poll function being called unnecessarily. Async I2C read poll function now only looks for I2C transfer complete reload (TCR) interrupts, intead of TCR and transfer complete (TC) interrupts, since TC interrupts are not raised when AUTOEND bit is set.
-rw-r--r--embassy-stm32/src/i2c/v2.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 1f53a995d..50a25754e 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -617,9 +617,10 @@ impl<'d> I2c<'d, Async> {
617 restart, 617 restart,
618 timeout, 618 timeout,
619 )?; 619 )?;
620 } else if remaining_len == 0 { 620 if total_len <= 255 {
621 return Poll::Ready(Ok(())); 621 return Poll::Ready(Ok(()));
622 } else if !(isr.tcr() || isr.tc()) { 622 }
623 } else if isr.tcr() {
623 // poll_fn was woken without an interrupt present 624 // poll_fn was woken without an interrupt present
624 return Poll::Pending; 625 return Poll::Pending;
625 } else { 626 } else {
@@ -628,6 +629,11 @@ impl<'d> I2c<'d, Async> {
628 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { 629 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) {
629 return Poll::Ready(Err(e)); 630 return Poll::Ready(Err(e));
630 } 631 }
632 // Return here if we are on last chunk,
633 // end of transfer will be awaited with the DMA below
634 if last_piece {
635 return Poll::Ready(Ok(()));
636 }
631 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 637 self.info.regs.cr1().modify(|w| w.set_tcie(true));
632 } 638 }
633 639