Skip to content

Commit ccfc7db

Browse files
authored
Add files via upload
1 parent ce20340 commit ccfc7db

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

cores/arduino/SERCOM.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)