From c0408b69e48182576f1cd26211df4c4986de782b 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 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/i2c.rs b/src/i2c.rs index 1420e6c2..ff6a66d9 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -219,17 +219,21 @@ 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 +351,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()); }