@@ -285,7 +285,12 @@ impl<I2C: Instance> I2c<I2C> {
285
285
/// Sends START and Address for writing
286
286
#[ inline( always) ]
287
287
fn prepare_write ( & self , addr : u8 ) -> Result < ( ) , Error > {
288
- // Wait until a previous STOP condition finishes
288
+ // Wait until a previous STOP condition finishes. When the previous
289
+ // STOP was generated inside an ISR (e.g. DMA interrupt handler),
290
+ // the ISR returns without waiting for the STOP condition to finish.
291
+ // It is possible that the STOP condition is still being generated
292
+ // when we reach here, so we wait until it finishes before proceeding
293
+ // to start a new transaction.
289
294
while self . i2c . cr1 . read ( ) . stop ( ) . bit_is_set ( ) { }
290
295
291
296
// Send a START condition
@@ -330,7 +335,12 @@ impl<I2C: Instance> I2c<I2C> {
330
335
331
336
/// Sends START and Address for reading
332
337
fn prepare_read ( & self , addr : u8 ) -> Result < ( ) , Error > {
333
- // Wait until a previous STOP condition finishes
338
+ // Wait until a previous STOP condition finishes. When the previous
339
+ // STOP was generated inside an ISR (e.g. DMA interrupt handler),
340
+ // the ISR returns without waiting for the STOP condition to finish.
341
+ // It is possible that the STOP condition is still being generated
342
+ // when we reach here, so we wait until it finishes before proceeding
343
+ // to start a new transaction.
334
344
while self . i2c . cr1 . read ( ) . stop ( ) . bit_is_set ( ) { }
335
345
336
346
// Send a START condition and set ACK bit
@@ -449,6 +459,13 @@ impl<I2C: Instance> I2c<I2C> {
449
459
// Receive last byte
450
460
* last = self . recv_byte ( ) ?;
451
461
462
+ // Wait for the STOP to be sent. Otherwise, the interface will still be
463
+ // busy for a while after this function returns. Immediate following
464
+ // operations through the DMA handle might thus encounter `WouldBlock`
465
+ // error. Instead, we should make sure that the interface becomes idle
466
+ // before returning.
467
+ while self . i2c . cr1 . read ( ) . stop ( ) . bit_is_set ( ) { }
468
+
452
469
// Fallthrough is success
453
470
Ok ( ( ) )
454
471
} else {
@@ -468,6 +485,13 @@ impl<I2C: Instance> I2c<I2C> {
468
485
// Send a STOP condition
469
486
self . i2c . cr1 . modify ( |_, w| w. stop ( ) . set_bit ( ) ) ;
470
487
488
+ // Wait for the STOP to be sent. Otherwise, the interface will still be
489
+ // busy for a while after this function returns. Immediate following
490
+ // operations through the DMA handle might thus encounter `WouldBlock`
491
+ // error. Instead, we should make sure that the interface becomes idle
492
+ // before returning.
493
+ while self . i2c . cr1 . read ( ) . stop ( ) . bit_is_set ( ) { }
494
+
471
495
// Fallthrough is success
472
496
Ok ( ( ) )
473
497
}
@@ -482,6 +506,13 @@ impl<I2C: Instance> I2c<I2C> {
482
506
// Send a STOP condition
483
507
self . i2c . cr1 . modify ( |_, w| w. stop ( ) . set_bit ( ) ) ;
484
508
509
+ // Wait for the STOP to be sent. Otherwise, the interface will still be
510
+ // busy for a while after this function returns. Immediate following
511
+ // operations through the DMA handle might thus encounter `WouldBlock`
512
+ // error. Instead, we should make sure that the interface becomes idle
513
+ // before returning.
514
+ while self . i2c . cr1 . read ( ) . stop ( ) . bit_is_set ( ) { }
515
+
485
516
// Fallthrough is success
486
517
Ok ( ( ) )
487
518
}
0 commit comments