From a3b037ff9d328eb92e0ded1320466f6e1b59e893 Mon Sep 17 00:00:00 2001 From: WillaWillNot Date: Mon, 10 Nov 2025 17:03:50 -0500 Subject: Added TXDR flush via TXE set to the drop guard for write_dma_internal_slave; factored in remaining DMA transfers for the return values for write_dma_internal_slave and read_dma_internal_slave --- embassy-stm32/CHANGELOG.md | 1 + embassy-stm32/src/i2c/v2.rs | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 8a53c9f03..33c7b5da5 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -53,6 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat: stm32/spi: added support for slave mode ([#4388](https://github.com/embassy-rs/embassy/pull/4388)) - chore: Updated stm32-metapac and stm32-data dependencies - adc: reogranize and cleanup somewhat. require sample_time to be passed on conversion +- fix: stm32/i2c v2 slave: prevent misaligned reads, error false positives, and incorrect counts of bytes read/written ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 57a7acee7..4527e55b9 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1235,6 +1235,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { regs.cr1().modify(|w| w.set_tcie(true)); Poll::Pending } else if isr.stopf() { + remaining_len = remaining_len.saturating_add(dma_transfer.get_remaining_transfers() as usize); regs.icr().write(|reg| reg.set_stopcf(true)); let poll = Poll::Ready(Ok(total_len - remaining_len)); poll @@ -1274,7 +1275,8 @@ impl<'d> I2c<'d, Async, MultiMaster> { w.set_txdmaen(false); w.set_stopie(false); w.set_tcie(false); - }) + }); + regs.isr().write(|w| w.set_txe(true)); }); let state = self.state; @@ -1297,6 +1299,11 @@ impl<'d> I2c<'d, Async, MultiMaster> { self.info.regs.cr1().modify(|w| w.set_tcie(true)); Poll::Pending } else if isr.stopf() { + let mut leftover_bytes = dma_transfer.get_remaining_transfers(); + if !self.info.regs.isr().read().txe() { + leftover_bytes = leftover_bytes.saturating_add(1); + } + remaining_len = remaining_len.saturating_add(leftover_bytes as usize); self.info.regs.icr().write(|reg| reg.set_stopcf(true)); if remaining_len > 0 { dma_transfer.request_pause(); -- cgit