@@ -246,6 +246,9 @@ where
246
246
247
247
/// Generate START condition
248
248
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 ( ) ;
249
252
self . i2c . cr1 . modify ( |_, w| w. start ( ) . set_bit ( ) ) ;
250
253
}
251
254
@@ -262,6 +265,12 @@ where
262
265
self . i2c . cr1 . modify ( |_, w| w. stop ( ) . set_bit ( ) ) ;
263
266
}
264
267
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
+
265
274
/// Releases the I2C peripheral and associated pins
266
275
pub fn release ( self ) -> ( I2C , PINS ) {
267
276
( self . i2c , self . pins )
@@ -279,21 +288,34 @@ where
279
288
{
280
289
fn check_and_clear_error_flags ( & self ) -> Result < pac:: i2c1:: sr1:: R , Error > {
281
290
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
+ }
296
317
}
318
+ Ok ( sr1)
297
319
}
298
320
299
321
/// Check if STOP condition is generated
@@ -339,19 +361,17 @@ where
339
361
break Ok ( ( ) ) ;
340
362
}
341
363
}
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 ) ;
347
367
}
368
+ Err ( e) => break Err ( e) ,
348
369
}
349
370
}
350
371
}
351
372
352
373
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 ( ) ;
355
375
356
376
self . i2c . dr . write ( |w| w. dr ( ) . bits ( bytes[ 0 ] ) ) ;
357
377
@@ -404,8 +424,7 @@ where
404
424
match buffer. len ( ) {
405
425
1 => {
406
426
self . i2c . cr1 . modify ( |_, w| w. ack ( ) . clear_bit ( ) ) ;
407
- self . i2c . sr1 . read ( ) ;
408
- self . i2c . sr2 . read ( ) ;
427
+ self . clear_addr_flag ( ) ;
409
428
self . send_stop ( ) ;
410
429
411
430
while self . check_and_clear_error_flags ( ) ?. rx_ne ( ) . bit_is_clear ( ) { }
@@ -418,8 +437,7 @@ where
418
437
self . i2c
419
438
. cr1
420
439
. modify ( |_, w| w. pos ( ) . set_bit ( ) . ack ( ) . set_bit ( ) ) ;
421
- self . i2c . sr1 . read ( ) ;
422
- self . i2c . sr2 . read ( ) ;
440
+ self . clear_addr_flag ( ) ;
423
441
self . i2c . cr1 . modify ( |_, w| w. ack ( ) . clear_bit ( ) ) ;
424
442
425
443
while self . check_and_clear_error_flags ( ) ?. btf ( ) . bit_is_clear ( ) { }
@@ -435,22 +453,21 @@ where
435
453
}
436
454
buffer_len => {
437
455
self . i2c . cr1 . modify ( |_, w| w. ack ( ) . set_bit ( ) ) ;
438
- self . i2c . sr1 . read ( ) ;
439
- self . i2c . sr2 . read ( ) ;
456
+ self . clear_addr_flag ( ) ;
440
457
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 ) ;
442
459
for byte in first_bytes {
443
460
while self . check_and_clear_error_flags ( ) ?. rx_ne ( ) . bit_is_clear ( ) { }
444
461
* byte = self . i2c . dr . read ( ) . dr ( ) . bits ( ) ;
445
462
}
446
463
447
464
while self . check_and_clear_error_flags ( ) ?. btf ( ) . bit_is_clear ( ) { }
448
465
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 ( ) ;
450
467
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 ( ) ;
452
469
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 ( ) ;
454
471
455
472
self . wait_for_stop ( ) ;
456
473
self . i2c . cr1 . modify ( |_, w| w. ack ( ) . set_bit ( ) ) ;
0 commit comments