diff options
| author | Sebastian Goll <[email protected]> | 2024-03-27 00:17:12 +0100 |
|---|---|---|
| committer | Sebastian Goll <[email protected]> | 2024-03-27 00:32:06 +0100 |
| commit | 2e2986c67b3a7a6a87695a359d630864c9eb6194 (patch) | |
| tree | fd935024c38ff1b8bfe6325618f07855de765124 | |
| parent | c1175bf7d850d6e9091853e6e9980b11407b5a21 (diff) | |
It is not necessary to wait for SB and MSL sequentially
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 72 |
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(); |
