aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Goll <[email protected]>2024-03-27 00:17:12 +0100
committerSebastian Goll <[email protected]>2024-03-27 00:32:06 +0100
commit2e2986c67b3a7a6a87695a359d630864c9eb6194 (patch)
treefd935024c38ff1b8bfe6325618f07855de765124
parentc1175bf7d850d6e9091853e6e9980b11407b5a21 (diff)
It is not necessary to wait for SB and MSL sequentially
-rw-r--r--embassy-stm32/src/i2c/v1.rs72
1 files changed, 14 insertions, 58 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 1e2205389..1e0eea33c 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -264,14 +264,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
264 timeout.check()?; 264 timeout.check()?;
265 } 265 }
266 266
267 // Also wait until signalled we're master and everything is waiting for us 267 // Check if we were the ones to generate START
268 while { 268 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() {
269 Self::check_and_clear_error_flags()?; 269 return Err(Error::Arbitration);
270
271 let sr2 = T::regs().sr2().read();
272 !sr2.msl() && !sr2.busy()
273 } {
274 timeout.check()?;
275 } 270 }
276 271
277 // Set up current address, we're trying to talk to 272 // Set up current address, we're trying to talk to
@@ -362,12 +357,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
362 timeout.check()?; 357 timeout.check()?;
363 } 358 }
364 359
365 // Also wait until signalled we're master and everything is waiting for us 360 // Check if we were the ones to generate START
366 while { 361 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() {
367 let sr2 = T::regs().sr2().read(); 362 return Err(Error::Arbitration);
368 !sr2.msl() && !sr2.busy()
369 } {
370 timeout.check()?;
371 } 363 }
372 364
373 // Set up current address, we're trying to talk to 365 // Set up current address, we're trying to talk to
@@ -522,27 +514,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
522 }) 514 })
523 .await?; 515 .await?;
524 516
525 // Also wait until signalled we're master and everything is waiting for us 517 // Check if we were the ones to generate START
526 Self::enable_interrupts(); 518 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() {
527 poll_fn(|cx| { 519 return Err(Error::Arbitration);
528 state.waker.register(cx.waker()); 520 }
529
530 match Self::check_and_clear_error_flags() {
531 Err(e) => Poll::Ready(Err(e)),
532 Ok(_) => {
533 let sr2 = T::regs().sr2().read();
534 if !sr2.msl() && !sr2.busy() {
535 // If we need to go around, then re-enable the interrupts, otherwise nothing
536 // can wake us up and we'll hang.
537 Self::enable_interrupts();
538 Poll::Pending
539 } else {
540 Poll::Ready(Ok(()))
541 }
542 }
543 }
544 })
545 .await?;
546 521
547 // Set up current address, we're trying to talk to 522 // Set up current address, we're trying to talk to
548 Self::enable_interrupts(); 523 Self::enable_interrupts();
@@ -723,29 +698,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
723 }) 698 })
724 .await?; 699 .await?;
725 700
726 // Also wait until signalled we're master and everything is waiting for us 701 // Check if we were the ones to generate START
727 Self::enable_interrupts(); 702 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() {
728 poll_fn(|cx| { 703 return Err(Error::Arbitration);
729 state.waker.register(cx.waker()); 704 }
730
731 // blocking read didn’t have a check_and_clear call here, but blocking write did so
732 // I’m adding it here in case that was an oversight.
733 match Self::check_and_clear_error_flags() {
734 Err(e) => Poll::Ready(Err(e)),
735 Ok(_) => {
736 let sr2 = T::regs().sr2().read();
737 if !sr2.msl() && !sr2.busy() {
738 // If we need to go around, then re-enable the interrupts, otherwise nothing
739 // can wake us up and we'll hang.
740 Self::enable_interrupts();
741 Poll::Pending
742 } else {
743 Poll::Ready(Ok(()))
744 }
745 }
746 }
747 })
748 .await?;
749 705
750 // Set up current address, we're trying to talk to 706 // Set up current address, we're trying to talk to
751 Self::enable_interrupts(); 707 Self::enable_interrupts();