Skip to content

Commit 5337975

Browse files
authored
Merge pull request #736 from ZhiyaoMa98/master
Fix transmission termination in I2C DMA master read.
2 parents 7bbd349 + 92f9e43 commit 5337975

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111
- remove unneeded trait bound for methods that take in a `serial::Instance` and use the associated `RegisterBlock`
1212
- bump `sdio-host` to 0.9.0, refactor SDIO initialization [#734]
1313

14+
### Fixed
15+
16+
- Fix transmission termination in I2C master DMA read [#736]
17+
1418
## [v0.20.0] - 2024-01-14
1519

1620
### Changed

src/i2c/dma.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,21 @@ where
509509
// Send address
510510
self.send_address(addr, true)?;
511511

512+
// Note from STM32 RM0090:
513+
// When the number of bytes to be received is equal to or greater than two,
514+
// the DMA controller sends a hardware signal, EOT_1, corresponding to the
515+
// last but one data byte (number_of_bytes – 1). If, in the I2C_CR2 register,
516+
// the LAST bit is set, I2C automatically sends a NACK after the next byte
517+
// following EOT_1. The user can generate a Stop condition in the DMA
518+
// Transfer Complete interrupt routine if enabled.
512519
// On small sized array we need to set ACK=0 before ADDR cleared
513-
if buf_len <= 1 {
520+
if buf_len >= 2 {
521+
self.hal_i2c.i2c.cr2.modify(|_, w| w.last().set_bit());
522+
// When a single byte must be received: the NACK must be programmed during
523+
// EV6 event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag.
524+
// Then the user can program the STOP condition either after clearing ADDR
525+
// flag, or in the DMA Transfer Complete interrupt routine.
526+
} else {
514527
self.hal_i2c.i2c.cr1.modify(|_, w| w.ack().clear_bit());
515528
}
516529

@@ -570,6 +583,7 @@ where
570583
fn finish_transfer_with_result(&mut self, result: Result<(), Error>) {
571584
self.disable_dma_requests();
572585
self.disable_error_interrupt_generation();
586+
self.hal_i2c.i2c.cr2.modify(|_, w| w.last().clear_bit());
573587

574588
if let Err(Error::I2CError(super::Error::NoAcknowledge(_))) = &result {
575589
self.send_stop();

0 commit comments

Comments
 (0)