@@ -559,15 +559,22 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
559559 while ( !sercom->I2CM .INTFLAG .bit .MB )
560560 {
561561 // Wait transmission complete
562+
563+ // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7).
564+ // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR
565+ if (sercom->I2CM .INTFLAG .bit .ERROR ) {
566+ return false ;
567+ }
562568 }
563569 }
564570 else // Read mode
565571 {
566572 while ( !sercom->I2CM .INTFLAG .bit .SB )
567573 {
568574 // If the slave NACKS the address, the MB bit will be set.
575+ // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register
569576 // In that case, send a stop condition and return false.
570- if (sercom->I2CM .INTFLAG .bit .MB ) {
577+ if (sercom->I2CM .INTFLAG .bit .ERROR || sercom-> I2CM . INTFLAG . bit . MB ) {
571578 sercom->I2CM .CTRLB .bit .CMD = 3 ; // Stop condition
572579 return false ;
573580 }
@@ -600,7 +607,8 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
600607
601608 // If a bus error occurs, the MB bit may never be set.
602609 // Check the bus error bit and bail if it's set.
603- if (sercom->I2CM .STATUS .bit .BUSERR ) {
610+ // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR
611+ if (sercom->I2CM .INTFLAG .bit .ERROR ) {
604612 return false ;
605613 }
606614 }
@@ -704,6 +712,15 @@ uint8_t SERCOM::readDataWIRE( void )
704712 while ( sercom->I2CM .INTFLAG .bit .SB == 0 )
705713 {
706714 // Waiting complete receive
715+ // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register
716+ // In that case, send a stop condition and return false.
717+ // readDataWIRE should really be able to indicate an error (which would never be used
718+ // because the readDataWIRE caller should have checked availableWIRE() first and timed it
719+ // out if the data never showed up
720+ if (sercom->I2CM .INTFLAG .bit .ERROR || sercom->I2CM .INTFLAG .bit .MB ) {
721+ sercom->I2CM .CTRLB .bit .CMD = 3 ; // Stop condition
722+ return 0xFF ;
723+ }
707724 }
708725
709726 return sercom->I2CM .DATA .bit .DATA ;
0 commit comments