@@ -524,28 +524,41 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
524524 // Address Transmitted
525525 if ( flag == WIRE_WRITE_FLAG ) // Write mode
526526 {
527- while ( !sercom->I2CM .INTFLAG .bit .MB )
527+ // The loop takes about 100us @ 100kHz baudrate.
528+ // Timeout: 20ms = 10000*2us
529+ for (uint16_t tmr = 10000 ; tmr; tmr--)
528530 {
531+ if (sercom->I2CM .INTFLAG .bit .MB ) // byte is transmitted
532+ {
533+ // Check for loss of arbitration (multiple masters starting communication at the same time)
534+ if (!isBusOwnerWIRE ())
535+ {
536+ // Restart communication
537+ sercom->I2CM .ADDR .bit .ADDR = address;
538+ }
539+ else
540+ {
541+ break ;
542+ }
543+ }
529544 // Wait transmission complete
530- }
531- // Check for loss of arbitration (multiple masters starting communication at the same time)
532- if (!isBusOwnerWIRE ())
533- {
534- // Restart communication
535- startTransmissionWIRE (address >> 1 , flag);
545+ delayMicroseconds (2 ); // wait 2us
536546 }
537547 }
538548 else // Read mode
539549 {
540- while ( !sercom->I2CM .INTFLAG .bit .SB )
550+ // The loop takes about 200us @ 100kHz baudrate.
551+ // Timeout: 20ms = 10000*2us
552+ for (uint16_t tmr = 10000 ; tmr && !sercom->I2CM .INTFLAG .bit .SB ; tmr--)
541553 {
542- // If the slave NACKS the address, the MB bit will be set.
543- // In that case, send a stop condition and return false.
544- if (sercom->I2CM .INTFLAG .bit .MB ) {
545- sercom->I2CM .CTRLB .bit .CMD = 3 ; // Stop condition
546- return false ;
547- }
554+ // If the slave NACKS the address, the MB bit will be set.
555+ // In that case, send a stop condition and return false.
556+ if (sercom->I2CM .INTFLAG .bit .MB ) {
557+ sercom->I2CM .CTRLB .bit .CMD = 3 ; // Stop condition
558+ return false ;
559+ }
548560 // Wait transmission complete
561+ delayMicroseconds (2 ); // wait 2us
549562 }
550563
551564 // Clean the 'Slave on Bus' flag, for further usage.
@@ -569,14 +582,16 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
569582 // Send data
570583 sercom->I2CM .DATA .bit .DATA = data;
571584
572- // Wait transmission successful
573- while (!sercom->I2CM .INTFLAG .bit .MB ) {
574-
585+ // Wait transmission successful
586+ // The loop takes about 100us @ 100kHz baudrate.
587+ // Timeout: 20ms = 10000*2us
588+ for (uint16_t tmr = 10000 ; tmr && !sercom->I2CM .INTFLAG .bit .MB ; tmr--) {
575589 // If a bus error occurs, the MB bit may never be set.
576590 // Check the bus error bit and bail if it's set.
577591 if (sercom->I2CM .STATUS .bit .BUSERR ) {
578592 return false ;
579593 }
594+ delayMicroseconds (2 ); // wait 2us
580595 }
581596
582597 // Problems on line? nack received?
0 commit comments