Skip to content
Snippets Groups Projects
Commit 0bfeec7f authored by Erin Tomson's avatar Erin Tomson
Browse files

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.
parent f2cfe524
No related branches found
No related tags found
No related merge requests found
......@@ -493,6 +493,12 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
{
while( !sercom->I2CM.INTFLAG.bit.SB )
{
// If the slave NACKS the address, the MB bit will be set.
// In that case, send a stop condition and return false.
if (sercom->I2CM.INTFLAG.bit.MB) {
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
return false;
}
// Wait transmission complete
}
......@@ -518,7 +524,14 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
sercom->I2CM.DATA.bit.DATA = data;
//Wait transmission successful
while(!sercom->I2CM.INTFLAG.bit.MB);
while(!sercom->I2CM.INTFLAG.bit.MB) {
// If a bus error occurs, the MB bit may never be set.
// Check the bus error bit and bail if it's set.
if (sercom->I2CM.STATUS.bit.BUSERR) {
return false;
}
}
//Problems on line? nack received?
if(sercom->I2CM.STATUS.bit.RXNACK)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment