Skip to content

Commit 7dfd77f

Browse files
pixelpixiaethaniel
authored andcommitted
Fix two bugs that can cause deadlock conditions when i2c bus errors occur.
The first occurs when starting a read transaction from a slave that doesn't respond. The code would wait until the SB (slave on bus) bit is set in the INTFLAGS register, but when a nack occurs that never happens so we're stuck in an infinite loop. The fix is to also look for the MB flag to be set. If it is, issue a stop condition and return. The second happens when a bus error (ie, an illegal stop condition) occurs while sending data as a master. In that case we are waiting for the MB (master on bus) flag to be set. When a bus error occurs that never happens, so again we end up in an infinite loop. The fix here is to also look for the BUSERR flag to be set. If it is, return an error condition.
1 parent 328f838 commit 7dfd77f

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

cores/arduino/SERCOM.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
493493
{
494494
while( !sercom->I2CM.INTFLAG.bit.SB )
495495
{
496+
// If the slave NACKS the address, the MB bit will be set.
497+
// In that case, send a stop condition and return false.
498+
if (sercom->I2CM.INTFLAG.bit.MB) {
499+
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
500+
return false;
501+
}
496502
// Wait transmission complete
497503
}
498504

@@ -518,7 +524,14 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
518524
sercom->I2CM.DATA.bit.DATA = data;
519525

520526
//Wait transmission successful
521-
while(!sercom->I2CM.INTFLAG.bit.MB);
527+
while(!sercom->I2CM.INTFLAG.bit.MB) {
528+
529+
// If a bus error occurs, the MB bit may never be set.
530+
// Check the bus error bit and bail if it's set.
531+
if (sercom->I2CM.STATUS.bit.BUSERR) {
532+
return false;
533+
}
534+
}
522535

523536
//Problems on line? nack received?
524537
if(sercom->I2CM.STATUS.bit.RXNACK)

0 commit comments

Comments
 (0)