Skip to content

Commit 4efaa88

Browse files
committed
include #298
1 parent 91c0110 commit 4efaa88

File tree

2 files changed

+64
-43
lines changed

2 files changed

+64
-43
lines changed

src/i2c.rs

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ where
246246

247247
/// Generate START condition
248248
fn send_start(&mut self) {
249+
// Clear all pending error bits
250+
// NOTE(unsafe): Writing 0 clears the r/w bits and has no effect on the r bits
251+
self.i2c.sr1.reset();
249252
self.i2c.cr1.modify(|_, w| w.start().set_bit());
250253
}
251254

@@ -262,6 +265,12 @@ where
262265
self.i2c.cr1.modify(|_, w| w.stop().set_bit());
263266
}
264267

268+
/// Clears the I2C ADDR pending flag
269+
fn clear_addr_flag(&self) {
270+
self.i2c.sr1.read();
271+
self.i2c.sr2.read();
272+
}
273+
265274
/// Releases the I2C peripheral and associated pins
266275
pub fn release(self) -> (I2C, PINS) {
267276
(self.i2c, self.pins)
@@ -279,21 +288,34 @@ where
279288
{
280289
fn check_and_clear_error_flags(&self) -> Result<pac::i2c1::sr1::R, Error> {
281290
let sr1 = self.i2c.sr1.read();
282-
if sr1.berr().bit_is_set() {
283-
self.i2c.sr1.write(|w| w.berr().clear_bit());
284-
Err(Error::Bus)
285-
} else if sr1.arlo().bit_is_set() {
286-
self.i2c.sr1.write(|w| w.arlo().clear_bit());
287-
Err(Error::Arbitration)
288-
} else if sr1.af().bit_is_set() {
289-
self.i2c.sr1.write(|w| w.af().clear_bit());
290-
Err(Error::Acknowledge)
291-
} else if sr1.ovr().bit_is_set() {
292-
self.i2c.sr1.write(|w| w.ovr().clear_bit());
293-
Err(Error::Overrun)
294-
} else {
295-
Ok(sr1)
291+
if sr1.bits() != 0 {
292+
// Writing 1s in order to only clear the flag we spotted even
293+
// if the register gets modified externally
294+
// NOTE(unsafe): Writing 1 to registers which are cleared by 0 has no effect.
295+
// Similarly, writing to read-only registers has no effect
296+
if sr1.berr().bit_is_set() {
297+
self.i2c
298+
.sr1
299+
.write(|w| unsafe { w.bits(0xffff).berr().clear_bit() });
300+
return Err(Error::Bus);
301+
} else if sr1.arlo().bit_is_set() {
302+
self.i2c
303+
.sr1
304+
.write(|w| unsafe { w.bits(0xffff).arlo().clear_bit() });
305+
return Err(Error::Arbitration);
306+
} else if sr1.af().bit_is_set() {
307+
self.i2c
308+
.sr1
309+
.write(|w| unsafe { w.bits(0xffff).af().clear_bit() });
310+
return Err(Error::Acknowledge);
311+
} else if sr1.ovr().bit_is_set() {
312+
self.i2c
313+
.sr1
314+
.write(|w| unsafe { w.bits(0xffff).ovr().clear_bit() });
315+
return Err(Error::Overrun);
316+
}
296317
}
318+
Ok(sr1)
297319
}
298320

299321
/// Check if STOP condition is generated
@@ -339,19 +361,17 @@ where
339361
break Ok(());
340362
}
341363
}
342-
Err(e) => {
343-
if let Error::Acknowledge = e {
344-
self.send_stop();
345-
}
346-
break Err(e);
364+
Err(Error::Acknowledge) => {
365+
self.send_stop();
366+
break Err(Error::Acknowledge);
347367
}
368+
Err(e) => break Err(e),
348369
}
349370
}
350371
}
351372

352373
fn write_bytes_and_wait(&mut self, bytes: &[u8]) -> Result<(), Error> {
353-
self.i2c.sr1.read();
354-
self.i2c.sr2.read();
374+
self.clear_addr_flag();
355375

356376
self.i2c.dr.write(|w| w.dr().bits(bytes[0]));
357377

@@ -404,8 +424,7 @@ where
404424
match buffer.len() {
405425
1 => {
406426
self.i2c.cr1.modify(|_, w| w.ack().clear_bit());
407-
self.i2c.sr1.read();
408-
self.i2c.sr2.read();
427+
self.clear_addr_flag();
409428
self.send_stop();
410429

411430
while self.check_and_clear_error_flags()?.rx_ne().bit_is_clear() {}
@@ -418,8 +437,7 @@ where
418437
self.i2c
419438
.cr1
420439
.modify(|_, w| w.pos().set_bit().ack().set_bit());
421-
self.i2c.sr1.read();
422-
self.i2c.sr2.read();
440+
self.clear_addr_flag();
423441
self.i2c.cr1.modify(|_, w| w.ack().clear_bit());
424442

425443
while self.check_and_clear_error_flags()?.btf().bit_is_clear() {}
@@ -435,22 +453,21 @@ where
435453
}
436454
buffer_len => {
437455
self.i2c.cr1.modify(|_, w| w.ack().set_bit());
438-
self.i2c.sr1.read();
439-
self.i2c.sr2.read();
456+
self.clear_addr_flag();
440457

441-
let (first_bytes, last_two_bytes) = buffer.split_at_mut(buffer_len - 3);
458+
let (first_bytes, last_3_bytes) = buffer.split_at_mut(buffer_len - 3);
442459
for byte in first_bytes {
443460
while self.check_and_clear_error_flags()?.rx_ne().bit_is_clear() {}
444461
*byte = self.i2c.dr.read().dr().bits();
445462
}
446463

447464
while self.check_and_clear_error_flags()?.btf().bit_is_clear() {}
448465
self.i2c.cr1.modify(|_, w| w.ack().clear_bit());
449-
last_two_bytes[0] = self.i2c.dr.read().dr().bits();
466+
last_3_bytes[0] = self.i2c.dr.read().dr().bits();
450467
self.send_stop();
451-
last_two_bytes[1] = self.i2c.dr.read().dr().bits();
468+
last_3_bytes[1] = self.i2c.dr.read().dr().bits();
452469
while self.check_and_clear_error_flags()?.rx_ne().bit_is_clear() {}
453-
last_two_bytes[2] = self.i2c.dr.read().dr().bits();
470+
last_3_bytes[2] = self.i2c.dr.read().dr().bits();
454471

455472
self.wait_for_stop();
456473
self.i2c.cr1.modify(|_, w| w.ack().set_bit());

src/i2c/blocking.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,25 @@ macro_rules! wait_for_flag {
117117
($i2c:expr, $flag:ident) => {{
118118
let sr1 = $i2c.sr1.read();
119119

120+
// Writing 1s in order to only clear the flag we spotted even
121+
// if the register gets modified externally
122+
// NOTE(unsafe): Writing 1 to registers which are cleared by 0 has no effect.
123+
// Similarly, writing to read-only registers has no effect
120124
if sr1.berr().bit_is_set() {
121-
$i2c.sr1.write(|w| w.berr().clear_bit());
125+
$i2c.sr1
126+
.write(|w| unsafe { w.bits(0xffff).berr().clear_bit() });
122127
Err(Other(Error::Bus))
123128
} else if sr1.arlo().bit_is_set() {
124-
$i2c.sr1.write(|w| w.arlo().clear_bit());
129+
$i2c.sr1
130+
.write(|w| unsafe { w.bits(0xffff).arlo().clear_bit() });
125131
Err(Other(Error::Arbitration))
126132
} else if sr1.af().bit_is_set() {
127-
$i2c.sr1.write(|w| w.af().clear_bit());
133+
$i2c.sr1
134+
.write(|w| unsafe { w.bits(0xffff).af().clear_bit() });
128135
Err(Other(Error::Acknowledge))
129136
} else if sr1.ovr().bit_is_set() {
130-
$i2c.sr1.write(|w| w.ovr().clear_bit());
137+
$i2c.sr1
138+
.write(|w| unsafe { w.bits(0xffff).ovr().clear_bit() });
131139
Err(Other(Error::Overrun))
132140
} else if sr1.$flag().bit_is_set() {
133141
Ok(())
@@ -237,8 +245,7 @@ where
237245
}
238246

239247
fn write_bytes_and_wait(&mut self, bytes: &[u8]) -> NbResult<(), Error> {
240-
self.nb.i2c.sr1.read();
241-
self.nb.i2c.sr2.read();
248+
self.nb.clear_addr_flag();
242249

243250
self.nb.i2c.dr.write(|w| w.dr().bits(bytes[0]));
244251

@@ -291,8 +298,7 @@ where
291298
match buffer.len() {
292299
1 => {
293300
self.nb.i2c.cr1.modify(|_, w| w.ack().clear_bit());
294-
self.nb.i2c.sr1.read();
295-
self.nb.i2c.sr2.read();
301+
self.nb.clear_addr_flag();
296302
self.nb.send_stop();
297303

298304
busy_wait_cycles!(wait_for_flag!(self.nb.i2c, rx_ne), self.timeouts.data)?;
@@ -306,8 +312,7 @@ where
306312
.i2c
307313
.cr1
308314
.modify(|_, w| w.pos().set_bit().ack().set_bit());
309-
self.nb.i2c.sr1.read();
310-
self.nb.i2c.sr2.read();
315+
self.nb.clear_addr_flag();
311316
self.nb.i2c.cr1.modify(|_, w| w.ack().clear_bit());
312317

313318
busy_wait_cycles!(wait_for_flag!(self.nb.i2c, btf), self.timeouts.data)?;
@@ -324,8 +329,7 @@ where
324329
}
325330
buffer_len => {
326331
self.nb.i2c.cr1.modify(|_, w| w.ack().set_bit());
327-
self.nb.i2c.sr1.read();
328-
self.nb.i2c.sr2.read();
332+
self.nb.clear_addr_flag();
329333

330334
let (first_bytes, last_two_bytes) = buffer.split_at_mut(buffer_len - 3);
331335
for byte in first_bytes {

0 commit comments

Comments
 (0)