aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorFabian Wolter <[email protected]>2025-09-02 21:17:47 +0200
committerFabian Wolter <[email protected]>2025-09-02 21:18:08 +0200
commit56f3c7a8c72356d9e21d5ef13e60d869ffd8cdf2 (patch)
tree09cdbbfe7a1f65fc8fddb375ff6e967a74e7e1aa /embassy-stm32
parent1405b1affa1b81bb50e6a39456793d968d39f63f (diff)
stm32/i2c: fix failure of subsequent transmissions after NACK
When a slave responds with a NACK in blocking I²C master mode, all subsequent transmissions send only the address followed immediately by a STOP. This happens because the current implementation sets I2C_CR2.STOP = 1 whenever any error (including a NACK) occurs. As a result, the STOP bit is already set when the next transmission starts. According to the reference manual: "If a NACK is received: […] a STOP condition is automatically sent […]" This bug was not triggered until #4454 was merged.
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/i2c/v2.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 3b09f1b34..6b20a601b 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -454,7 +454,8 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
454 // (START has been ACKed or last byte when 454 // (START has been ACKed or last byte when
455 // through) 455 // through)
456 if let Err(err) = self.wait_txis(timeout) { 456 if let Err(err) = self.wait_txis(timeout) {
457 if send_stop { 457 if send_stop && err != Error::Nack {
458 // STOP is sent automatically if a NACK was received
458 self.master_stop(); 459 self.master_stop();
459 } 460 }
460 return Err(err); 461 return Err(err);
@@ -548,7 +549,9 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
548 (idx != last_slice_index) || (slice_len > 255), 549 (idx != last_slice_index) || (slice_len > 255),
549 timeout, 550 timeout,
550 ) { 551 ) {
551 self.master_stop(); 552 if err != Error::Nack {
553 self.master_stop();
554 }
552 return Err(err); 555 return Err(err);
553 } 556 }
554 } 557 }
@@ -561,7 +564,9 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
561 (number != last_chunk_idx) || (idx != last_slice_index), 564 (number != last_chunk_idx) || (idx != last_slice_index),
562 timeout, 565 timeout,
563 ) { 566 ) {
564 self.master_stop(); 567 if err != Error::Nack {
568 self.master_stop();
569 }
565 return Err(err); 570 return Err(err);
566 } 571 }
567 } 572 }
@@ -571,7 +576,9 @@ impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
571 // (START has been ACKed or last byte when 576 // (START has been ACKed or last byte when
572 // through) 577 // through)
573 if let Err(err) = self.wait_txis(timeout) { 578 if let Err(err) = self.wait_txis(timeout) {
574 self.master_stop(); 579 if err != Error::Nack {
580 self.master_stop();
581 }
575 return Err(err); 582 return Err(err);
576 } 583 }
577 584