aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-02-16 23:07:10 +0000
committerGitHub <[email protected]>2025-02-16 23:07:10 +0000
commit0453f7ddb24b55bb080f24c22b6655f0014b21c2 (patch)
treee845e73625f8fa3f1dd147b88f7885966a0409ed
parentd01a299321e7ac3a7a0d4e4301f76ba38f7a2eae (diff)
parent7f4cce536aa14010b723885bdf632f0f22182cb1 (diff)
Merge pull request #3888 from Fredrik-Reinholdsen/main
fix: Fix for async I2C v2 driver sequential read/write reads. Fixes #3887
-rw-r--r--embassy-stm32/src/i2c/v2.rs22
1 files changed, 10 insertions, 12 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 05ac9afcc..8801fddf0 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -438,6 +438,7 @@ impl<'d> I2c<'d, Async> {
438 write: &[u8], 438 write: &[u8],
439 first_slice: bool, 439 first_slice: bool,
440 last_slice: bool, 440 last_slice: bool,
441 send_stop: bool,
441 timeout: Timeout, 442 timeout: Timeout,
442 ) -> Result<(), Error> { 443 ) -> Result<(), Error> {
443 let total_len = write.len(); 444 let total_len = write.len();
@@ -505,10 +506,12 @@ impl<'d> I2c<'d, Async> {
505 .await?; 506 .await?;
506 507
507 dma_transfer.await; 508 dma_transfer.await;
508
509 if last_slice { 509 if last_slice {
510 // This should be done already 510 // This should be done already
511 self.wait_tc(timeout)?; 511 self.wait_tc(timeout)?;
512 }
513
514 if last_slice & send_stop {
512 self.master_stop(); 515 self.master_stop();
513 } 516 }
514 517
@@ -556,16 +559,16 @@ impl<'d> I2c<'d, Async> {
556 self.info, 559 self.info,
557 address, 560 address,
558 total_len.min(255), 561 total_len.min(255),
559 Stop::Software, 562 Stop::Automatic,
560 total_len > 255, 563 total_len > 255,
561 restart, 564 restart,
562 timeout, 565 timeout,
563 )?; 566 )?;
567 } else if remaining_len == 0 {
568 return Poll::Ready(Ok(()));
564 } else if !(isr.tcr() || isr.tc()) { 569 } else if !(isr.tcr() || isr.tc()) {
565 // poll_fn was woken without an interrupt present 570 // poll_fn was woken without an interrupt present
566 return Poll::Pending; 571 return Poll::Pending;
567 } else if remaining_len == 0 {
568 return Poll::Ready(Ok(()));
569 } else { 572 } else {
570 let last_piece = remaining_len <= 255; 573 let last_piece = remaining_len <= 255;
571 574
@@ -581,11 +584,6 @@ impl<'d> I2c<'d, Async> {
581 .await?; 584 .await?;
582 585
583 dma_transfer.await; 586 dma_transfer.await;
584
585 // This should be done already
586 self.wait_tc(timeout)?;
587 self.master_stop();
588
589 drop(on_drop); 587 drop(on_drop);
590 588
591 Ok(()) 589 Ok(())
@@ -601,7 +599,7 @@ impl<'d> I2c<'d, Async> {
601 self.write_internal(address, write, true, timeout) 599 self.write_internal(address, write, true, timeout)
602 } else { 600 } else {
603 timeout 601 timeout
604 .with(self.write_dma_internal(address, write, true, true, timeout)) 602 .with(self.write_dma_internal(address, write, true, true, true, timeout))
605 .await 603 .await
606 } 604 }
607 } 605 }
@@ -623,7 +621,7 @@ impl<'d> I2c<'d, Async> {
623 let next = iter.next(); 621 let next = iter.next();
624 let is_last = next.is_none(); 622 let is_last = next.is_none();
625 623
626 let fut = self.write_dma_internal(address, c, first, is_last, timeout); 624 let fut = self.write_dma_internal(address, c, first, is_last, is_last, timeout);
627 timeout.with(fut).await?; 625 timeout.with(fut).await?;
628 first = false; 626 first = false;
629 current = next; 627 current = next;
@@ -650,7 +648,7 @@ impl<'d> I2c<'d, Async> {
650 if write.is_empty() { 648 if write.is_empty() {
651 self.write_internal(address, write, false, timeout)?; 649 self.write_internal(address, write, false, timeout)?;
652 } else { 650 } else {
653 let fut = self.write_dma_internal(address, write, true, true, timeout); 651 let fut = self.write_dma_internal(address, write, true, true, false, timeout);
654 timeout.with(fut).await?; 652 timeout.with(fut).await?;
655 } 653 }
656 654