From 8f19a2b537c90c2bf04f6e5ea9a7107f6e000067 Mon Sep 17 00:00:00 2001 From: Sebastian Goll Date: Wed, 20 Mar 2024 02:20:21 +0100 Subject: [PATCH] Avoid missing stop condition when write/read with empty read buffer --- embassy-stm32/src/i2c/v1.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 678568706..c96935d8f 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -367,6 +367,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { /// Blocking write, restart, read. pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { + // Check empty read buffer before starting transaction. Otherwise, we would not generate the + // stop condition below. + if read.is_empty() { + return Err(Error::Overrun); + } + let timeout = self.timeout(); self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?; @@ -381,6 +387,15 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { /// /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { + // Check empty read buffer before starting transaction. Otherwise, we would not generate the + // stop condition below. + if operations.iter().any(|op| match op { + Operation::Read(read) => read.is_empty(), + Operation::Write(_) => false, + }) { + return Err(Error::Overrun); + } + let timeout = self.timeout(); let mut operations = operations.iter_mut();