@@ -13,13 +13,17 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
1313 let regs = T :: info ( ) . regs ;
1414 let isr = regs. isr ( ) . read ( ) ;
1515
16- if isr. tcr ( ) || isr. tc ( ) {
16+ if isr. tcr ( ) || isr. tc ( ) || isr . nackf ( ) || isr . berr ( ) || isr . arlo ( ) || isr . ovr ( ) {
1717 T :: state ( ) . waker . wake ( ) ;
1818 }
19- // The flag can only be cleared by writting to nbytes, we won't do that here, so disable
20- // the interrupt
2119 critical_section:: with ( |_| {
22- regs. cr1 ( ) . modify ( |w| w. set_tcie ( false ) ) ;
20+ regs. cr1 ( ) . modify ( |w| {
21+ // The flag can only be cleared by writting to nbytes, we won't do that here
22+ w. set_tcie ( false ) ;
23+ // Error flags are to be read in the routines, so we also don't clear them here
24+ w. set_nackie ( false ) ;
25+ w. set_errie ( false ) ;
26+ } ) ;
2327 } ) ;
2428}
2529
@@ -449,6 +453,8 @@ impl<'d> I2c<'d, Async> {
449453 if first_slice {
450454 w. set_tcie ( true ) ;
451455 }
456+ w. set_nackie ( true ) ;
457+ w. set_errie ( true ) ;
452458 } ) ;
453459 let dst = regs. txdr ( ) . as_ptr ( ) as * mut u8 ;
454460
@@ -459,18 +465,41 @@ impl<'d> I2c<'d, Async> {
459465
460466 let on_drop = OnDrop :: new ( || {
461467 let regs = self . info . regs ;
468+ let isr = regs. isr ( ) . read ( ) ;
462469 regs. cr1 ( ) . modify ( |w| {
463- if last_slice {
470+ if last_slice || isr . nackf ( ) || isr . arlo ( ) || isr . berr ( ) || isr . ovr ( ) {
464471 w. set_txdmaen ( false ) ;
465472 }
466473 w. set_tcie ( false ) ;
467- } )
474+ w. set_nackie ( false ) ;
475+ w. set_errie ( false ) ;
476+ } ) ;
477+ regs. icr ( ) . write ( |w| {
478+ w. set_nackcf ( true ) ;
479+ w. set_berrcf ( true ) ;
480+ w. set_arlocf ( true ) ;
481+ w. set_ovrcf ( true ) ;
482+ } ) ;
468483 } ) ;
469484
470485 poll_fn ( |cx| {
471486 self . state . waker . register ( cx. waker ( ) ) ;
472487
473488 let isr = self . info . regs . isr ( ) . read ( ) ;
489+
490+ if isr. nackf ( ) {
491+ return Poll :: Ready ( Err ( Error :: Nack ) ) ;
492+ }
493+ if isr. arlo ( ) {
494+ return Poll :: Ready ( Err ( Error :: Arbitration ) ) ;
495+ }
496+ if isr. berr ( ) {
497+ return Poll :: Ready ( Err ( Error :: Bus ) ) ;
498+ }
499+ if isr. ovr ( ) {
500+ return Poll :: Ready ( Err ( Error :: Overrun ) ) ;
501+ }
502+
474503 if remaining_len == total_len {
475504 if first_slice {
476505 Self :: master_write (
@@ -531,6 +560,8 @@ impl<'d> I2c<'d, Async> {
531560 regs. cr1 ( ) . modify ( |w| {
532561 w. set_rxdmaen ( true ) ;
533562 w. set_tcie ( true ) ;
563+ w. set_nackie ( true ) ;
564+ w. set_errie ( true ) ;
534565 } ) ;
535566 let src = regs. rxdr ( ) . as_ptr ( ) as * mut u8 ;
536567
@@ -544,13 +575,35 @@ impl<'d> I2c<'d, Async> {
544575 regs. cr1 ( ) . modify ( |w| {
545576 w. set_rxdmaen ( false ) ;
546577 w. set_tcie ( false ) ;
547- } )
578+ w. set_nackie ( false ) ;
579+ w. set_errie ( false ) ;
580+ } ) ;
581+ regs. icr ( ) . write ( |w| {
582+ w. set_nackcf ( true ) ;
583+ w. set_berrcf ( true ) ;
584+ w. set_arlocf ( true ) ;
585+ w. set_ovrcf ( true ) ;
586+ } ) ;
548587 } ) ;
549588
550589 poll_fn ( |cx| {
551590 self . state . waker . register ( cx. waker ( ) ) ;
552591
553592 let isr = self . info . regs . isr ( ) . read ( ) ;
593+
594+ if isr. nackf ( ) {
595+ return Poll :: Ready ( Err ( Error :: Nack ) ) ;
596+ }
597+ if isr. arlo ( ) {
598+ return Poll :: Ready ( Err ( Error :: Arbitration ) ) ;
599+ }
600+ if isr. berr ( ) {
601+ return Poll :: Ready ( Err ( Error :: Bus ) ) ;
602+ }
603+ if isr. ovr ( ) {
604+ return Poll :: Ready ( Err ( Error :: Overrun ) ) ;
605+ }
606+
554607 if remaining_len == total_len {
555608 Self :: master_read (
556609 self . info ,
0 commit comments