Merge pull request #3888 from Fredrik-Reinholdsen/main

fix: Fix for async I2C v2 driver sequential read/write reads. Fixes #3887
This commit is contained in:
Dario Nieuwenhuis 2025-02-16 23:07:10 +00:00 committed by GitHub
commit 0453f7ddb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -438,6 +438,7 @@ impl<'d> I2c<'d, Async> {
write: &[u8], write: &[u8],
first_slice: bool, first_slice: bool,
last_slice: bool, last_slice: bool,
send_stop: bool,
timeout: Timeout, timeout: Timeout,
) -> Result<(), Error> { ) -> Result<(), Error> {
let total_len = write.len(); let total_len = write.len();
@ -505,10 +506,12 @@ impl<'d> I2c<'d, Async> {
.await?; .await?;
dma_transfer.await; dma_transfer.await;
if last_slice { if last_slice {
// This should be done already // This should be done already
self.wait_tc(timeout)?; self.wait_tc(timeout)?;
}
if last_slice & send_stop {
self.master_stop(); self.master_stop();
} }
@ -556,16 +559,16 @@ impl<'d> I2c<'d, Async> {
self.info, self.info,
address, address,
total_len.min(255), total_len.min(255),
Stop::Software, Stop::Automatic,
total_len > 255, total_len > 255,
restart, restart,
timeout, timeout,
)?; )?;
} else if remaining_len == 0 {
return Poll::Ready(Ok(()));
} else if !(isr.tcr() || isr.tc()) { } else if !(isr.tcr() || isr.tc()) {
// poll_fn was woken without an interrupt present // poll_fn was woken without an interrupt present
return Poll::Pending; return Poll::Pending;
} else if remaining_len == 0 {
return Poll::Ready(Ok(()));
} else { } else {
let last_piece = remaining_len <= 255; let last_piece = remaining_len <= 255;
@ -581,11 +584,6 @@ impl<'d> I2c<'d, Async> {
.await?; .await?;
dma_transfer.await; dma_transfer.await;
// This should be done already
self.wait_tc(timeout)?;
self.master_stop();
drop(on_drop); drop(on_drop);
Ok(()) Ok(())
@ -601,7 +599,7 @@ impl<'d> I2c<'d, Async> {
self.write_internal(address, write, true, timeout) self.write_internal(address, write, true, timeout)
} else { } else {
timeout timeout
.with(self.write_dma_internal(address, write, true, true, timeout)) .with(self.write_dma_internal(address, write, true, true, true, timeout))
.await .await
} }
} }
@ -623,7 +621,7 @@ impl<'d> I2c<'d, Async> {
let next = iter.next(); let next = iter.next();
let is_last = next.is_none(); let is_last = next.is_none();
let fut = self.write_dma_internal(address, c, first, is_last, timeout); let fut = self.write_dma_internal(address, c, first, is_last, is_last, timeout);
timeout.with(fut).await?; timeout.with(fut).await?;
first = false; first = false;
current = next; current = next;
@ -650,7 +648,7 @@ impl<'d> I2c<'d, Async> {
if write.is_empty() { if write.is_empty() {
self.write_internal(address, write, false, timeout)?; self.write_internal(address, write, false, timeout)?;
} else { } else {
let fut = self.write_dma_internal(address, write, true, true, timeout); let fut = self.write_dma_internal(address, write, true, true, false, timeout);
timeout.with(fut).await?; timeout.with(fut).await?;
} }