From d805d28601c73a4d34726bfb071bfc4ca38e204e Mon Sep 17 00:00:00 2001 From: TheZoq2 Date: Sat, 23 Jan 2021 10:27:20 +0100 Subject: [PATCH] Clear start bits before send --- src/i2c.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/i2c.rs b/src/i2c.rs index 1420e6c2..4ef3ddd0 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -219,17 +219,25 @@ macro_rules! wait_for_flag { ($i2c:expr, $flag:ident) => {{ let sr1 = $i2c.sr1.read(); + // Writing 1s in order to only clear the flag we spotted even + // if the register gets modified externally + // NOTE(unsafe): Writing 1 to registers which are cleared by 0 has no effect. + // Similarly, writing to read-only registers has no effect if sr1.berr().bit_is_set() { - $i2c.sr1.modify(|_r, w| w.berr().clear_bit()); + $i2c.sr1 + .write(|w| unsafe { w.bits(0xffff) }.berr().clear_bit()); Err(Other(Error::Bus)) } else if sr1.arlo().bit_is_set() { - $i2c.sr1.modify(|_r, w| w.arlo().clear_bit()); + $i2c.sr1 + .write(|w| unsafe { w.bits(0xffff) }.arlo().clear_bit()); Err(Other(Error::Arbitration)) } else if sr1.af().bit_is_set() { - $i2c.sr1.modify(|_r, w| w.af().clear_bit()); + $i2c.sr1 + .write(|w| unsafe { w.bits(0xffff) }.af().clear_bit()); Err(Other(Error::Acknowledge)) } else if sr1.ovr().bit_is_set() { - $i2c.sr1.modify(|_r, w| w.ovr().clear_bit()); + $i2c.sr1 + .write(|w| unsafe { w.bits(0xffff) }.ovr().clear_bit()); Err(Other(Error::Overrun)) } else if sr1.$flag().bit_is_set() { Ok(()) @@ -347,6 +355,9 @@ where /// Generate START condition fn send_start(&mut self) { + // Clear all pending error bits + // NOTE(unsafe): Writing 0 clears the r/w bits and has no effect on the r bits + self.i2c.sr1.write(|w| unsafe { w.bits(0) }); self.i2c.cr1.modify(|_, w| w.start().set_bit()); }