Skip to content

Commit e3e85d5

Browse files
asserta6facchinm
authored andcommitted
deadlock detect and early return in startTransmissionWIRE
1 parent 08629f9 commit e3e85d5

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

cores/arduino/SERCOM.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,19 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
499499
// 7-bits address + 1-bits R/W
500500
address = (address << 0x1ul) | flag;
501501

502+
// If another master owns the bus or the last bus owner has not properly
503+
// sent a stop, return failure early. This will prevent some misbehaved
504+
// devices from deadlocking here at the cost of the caller being responsible
505+
// for retrying the failed transmission. See SercomWireBusState for the
506+
// possible bus states.
507+
if(!isBusOwnerWIRE())
508+
{
509+
if( isBusBusyWIRE() || (isArbLostWIRE() && !isBusIdleWIRE()) )
510+
{
511+
return false;
512+
}
513+
}
514+
502515
// Wait idle or owner bus mode
503516
while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
504517

@@ -596,6 +609,16 @@ bool SERCOM::isBusOwnerWIRE( void )
596609
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
597610
}
598611

612+
bool SERCOM::isArbLostWIRE( void )
613+
{
614+
return sercom->I2CM.STATUS.bit.ARBLOST == 1;
615+
}
616+
617+
bool SERCOM::isBusBusyWIRE( void )
618+
{
619+
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_BUSY_STATE;
620+
}
621+
599622
bool SERCOM::isDataReadyWIRE( void )
600623
{
601624
return sercom->I2CS.INTFLAG.bit.DRDY;

cores/arduino/SERCOM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ class SERCOM
202202
bool isSlaveWIRE( void ) ;
203203
bool isBusIdleWIRE( void ) ;
204204
bool isBusOwnerWIRE( void ) ;
205+
bool isArbLostWIRE( void );
206+
bool isBusBusyWIRE( void );
205207
bool isDataReadyWIRE( void ) ;
206208
bool isStopDetectedWIRE( void ) ;
207209
bool isRestartDetectedWIRE( void ) ;

0 commit comments

Comments
 (0)