@@ -559,15 +559,22 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
559
559
while ( !sercom->I2CM .INTFLAG .bit .MB )
560
560
{
561
561
// 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
+ }
562
568
}
563
569
}
564
570
else // Read mode
565
571
{
566
572
while ( !sercom->I2CM .INTFLAG .bit .SB )
567
573
{
568
574
// 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
569
576
// 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 ) {
571
578
sercom->I2CM .CTRLB .bit .CMD = 3 ; // Stop condition
572
579
return false ;
573
580
}
@@ -600,7 +607,8 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
600
607
601
608
// If a bus error occurs, the MB bit may never be set.
602
609
// 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 ) {
604
612
return false ;
605
613
}
606
614
}
@@ -704,6 +712,15 @@ uint8_t SERCOM::readDataWIRE( void )
704
712
while ( sercom->I2CM .INTFLAG .bit .SB == 0 )
705
713
{
706
714
// 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
+ }
707
724
}
708
725
709
726
return sercom->I2CM .DATA .bit .DATA ;
0 commit comments