@@ -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
@@ -450,6 +454,8 @@ impl<'d> I2c<'d, Async> {
450454 if first_slice {
451455 w. set_tcie ( true ) ;
452456 }
457+ w. set_nackie ( true ) ;
458+ w. set_errie ( true ) ;
453459 } ) ;
454460 let dst = regs. txdr ( ) . as_ptr ( ) as * mut u8 ;
455461
@@ -460,18 +466,41 @@ impl<'d> I2c<'d, Async> {
460466
461467 let on_drop = OnDrop :: new ( || {
462468 let regs = self . info . regs ;
469+ let isr = regs. isr ( ) . read ( ) ;
463470 regs. cr1 ( ) . modify ( |w| {
464- if last_slice {
471+ if last_slice || isr . nackf ( ) || isr . arlo ( ) || isr . berr ( ) || isr . ovr ( ) {
465472 w. set_txdmaen ( false ) ;
466473 }
467474 w. set_tcie ( false ) ;
468- } )
475+ w. set_nackie ( false ) ;
476+ w. set_errie ( false ) ;
477+ } ) ;
478+ regs. icr ( ) . write ( |w| {
479+ w. set_nackcf ( true ) ;
480+ w. set_berrcf ( true ) ;
481+ w. set_arlocf ( true ) ;
482+ w. set_ovrcf ( true ) ;
483+ } ) ;
469484 } ) ;
470485
471486 poll_fn ( |cx| {
472487 self . state . waker . register ( cx. waker ( ) ) ;
473488
474489 let isr = self . info . regs . isr ( ) . read ( ) ;
490+
491+ if isr. nackf ( ) {
492+ return Poll :: Ready ( Err ( Error :: Nack ) ) ;
493+ }
494+ if isr. arlo ( ) {
495+ return Poll :: Ready ( Err ( Error :: Arbitration ) ) ;
496+ }
497+ if isr. berr ( ) {
498+ return Poll :: Ready ( Err ( Error :: Bus ) ) ;
499+ }
500+ if isr. ovr ( ) {
501+ return Poll :: Ready ( Err ( Error :: Overrun ) ) ;
502+ }
503+
475504 if remaining_len == total_len {
476505 if first_slice {
477506 Self :: master_write (
@@ -534,6 +563,8 @@ impl<'d> I2c<'d, Async> {
534563 regs. cr1 ( ) . modify ( |w| {
535564 w. set_rxdmaen ( true ) ;
536565 w. set_tcie ( true ) ;
566+ w. set_nackie ( true ) ;
567+ w. set_errie ( true ) ;
537568 } ) ;
538569 let src = regs. rxdr ( ) . as_ptr ( ) as * mut u8 ;
539570
@@ -547,13 +578,35 @@ impl<'d> I2c<'d, Async> {
547578 regs. cr1 ( ) . modify ( |w| {
548579 w. set_rxdmaen ( false ) ;
549580 w. set_tcie ( false ) ;
550- } )
581+ w. set_nackie ( false ) ;
582+ w. set_errie ( false ) ;
583+ } ) ;
584+ regs. icr ( ) . write ( |w| {
585+ w. set_nackcf ( true ) ;
586+ w. set_berrcf ( true ) ;
587+ w. set_arlocf ( true ) ;
588+ w. set_ovrcf ( true ) ;
589+ } ) ;
551590 } ) ;
552591
553592 poll_fn ( |cx| {
554593 self . state . waker . register ( cx. waker ( ) ) ;
555594
556595 let isr = self . info . regs . isr ( ) . read ( ) ;
596+
597+ if isr. nackf ( ) {
598+ return Poll :: Ready ( Err ( Error :: Nack ) ) ;
599+ }
600+ if isr. arlo ( ) {
601+ return Poll :: Ready ( Err ( Error :: Arbitration ) ) ;
602+ }
603+ if isr. berr ( ) {
604+ return Poll :: Ready ( Err ( Error :: Bus ) ) ;
605+ }
606+ if isr. ovr ( ) {
607+ return Poll :: Ready ( Err ( Error :: Overrun ) ) ;
608+ }
609+
557610 if remaining_len == total_len {
558611 Self :: master_read (
559612 self . info ,
0 commit comments