From b52e9a60eb929facd21eab2d524781e127f3e04b Mon Sep 17 00:00:00 2001 From: Sebastian Goll Date: Wed, 27 Mar 2024 10:39:33 +0100 Subject: [PATCH] Add missing check for empty buffer in asynchronous read_write() --- embassy-stm32/src/i2c/mod.rs | 4 ++++ embassy-stm32/src/i2c/v1.rs | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 9a91e2f25..d4d4aec5d 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -415,6 +415,10 @@ fn operation_frames<'a, 'b: 'a>( // Check empty read buffer before starting transaction. Otherwise, we would risk halting with an // error in the middle of the transaction. + // + // In principle, we could allow empty read frames within consecutive read operations, as long as + // at least one byte remains in the final (merged) read operation, but that makes the logic more + // complicated and error-prone. if operations.iter().any(|op| match op { Operation::Read(read) => read.is_empty(), Operation::Write(_) => false, diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 5c57a9ccc..d45c48b24 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -669,6 +669,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { RXDMA: crate::i2c::RxDma, TXDMA: crate::i2c::TxDma, { + // Check empty read buffer before starting transaction. Otherwise, we would not generate the + // stop condition below. + if read.is_empty() { + return Err(Error::Overrun); + } + self.write_frame(address, write, FrameOptions::FirstFrame).await?; self.read_frame(address, read, FrameOptions::FirstAndLastFrame).await }