Skip to content

Commit c0408b6

Browse files
committed
Clear start bits before send
1 parent d7c817f commit c0408b6

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/i2c.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,17 +219,21 @@ macro_rules! wait_for_flag {
219219
($i2c:expr, $flag:ident) => {{
220220
let sr1 = $i2c.sr1.read();
221221

222+
// Writing 1s in order to only clear the flag we spotted even
223+
// if the register gets modified externally
224+
// NOTE(unsafe): Writing 1 to registers which are cleared by 0 has no effect.
225+
// Similarly, writing to read-only registers has no effect
222226
if sr1.berr().bit_is_set() {
223-
$i2c.sr1.modify(|_r, w| w.berr().clear_bit());
227+
$i2c.sr1.write(|w| unsafe{w.bits(0xffff)}.berr().clear_bit());
224228
Err(Other(Error::Bus))
225229
} else if sr1.arlo().bit_is_set() {
226-
$i2c.sr1.modify(|_r, w| w.arlo().clear_bit());
230+
$i2c.sr1.write(|w| unsafe{w.bits(0xffff)}.arlo().clear_bit());
227231
Err(Other(Error::Arbitration))
228232
} else if sr1.af().bit_is_set() {
229-
$i2c.sr1.modify(|_r, w| w.af().clear_bit());
233+
$i2c.sr1.write(|w| unsafe{w.bits(0xffff)}.af().clear_bit());
230234
Err(Other(Error::Acknowledge))
231235
} else if sr1.ovr().bit_is_set() {
232-
$i2c.sr1.modify(|_r, w| w.ovr().clear_bit());
236+
$i2c.sr1.write(|w| unsafe{w.bits(0xffff)}.ovr().clear_bit());
233237
Err(Other(Error::Overrun))
234238
} else if sr1.$flag().bit_is_set() {
235239
Ok(())
@@ -347,6 +351,9 @@ where
347351

348352
/// Generate START condition
349353
fn send_start(&mut self) {
354+
// Clear all pending error bits
355+
// NOTE(unsafe): Writing 0 clears the r/w bits and has no effect on the r bits
356+
self.i2c.sr1.write(|w| unsafe{w.bits(0)});
350357
self.i2c.cr1.modify(|_, w| w.start().set_bit());
351358
}
352359

0 commit comments

Comments
 (0)