@@ -524,28 +524,41 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
524
524
// Address Transmitted
525
525
if ( flag == WIRE_WRITE_FLAG ) // Write mode
526
526
{
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--)
528
530
{
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
+ }
529
544
// 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
536
546
}
537
547
}
538
548
else // Read mode
539
549
{
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--)
541
553
{
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
+ }
548
560
// Wait transmission complete
561
+ delayMicroseconds (2 ); // wait 2us
549
562
}
550
563
551
564
// Clean the 'Slave on Bus' flag, for further usage.
@@ -569,14 +582,16 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
569
582
// Send data
570
583
sercom->I2CM .DATA .bit .DATA = data;
571
584
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--) {
575
589
// If a bus error occurs, the MB bit may never be set.
576
590
// Check the bus error bit and bail if it's set.
577
591
if (sercom->I2CM .STATUS .bit .BUSERR ) {
578
592
return false ;
579
593
}
594
+ delayMicroseconds (2 ); // wait 2us
580
595
}
581
596
582
597
// Problems on line? nack received?
0 commit comments