@@ -476,18 +476,38 @@ void SERCOM::initMasterWIRE( uint32_t baudrate )
476476
477477
478478 // Enable all interrupts
479- // sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;
479+ // sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;
480480
481- uint8_t speedBit = sercom->I2CM .CTRLA .bit .SPEED ;
482- uint32_t topSpeeds[3 ] = {400000 , 1000000 , 3400000 }; // {(sm/fm), (fm+), (hs)}
483- const uint32_t minBaudrate = freqRef / 512 ; // BAUD = 255: SAMD51 ~195kHz, SAMD21 ~94kHz
484- const uint32_t maxBaudrate = topSpeeds[speedBit];
481+ // Determine speed mode based on requested baudrate
482+ const uint32_t topSpeeds[3 ] = {400000 , 1000000 , 3400000 }; // {(sm/fm), (fm+), (hs)}
483+ uint8_t speedBit = 0 ;
484+ bool clockStretchMode = false ;
485+ sercom->I2CM .CTRLA .bit .SCLSM = 0 ; // See: 28.6.2.4.6
486+
487+ if (baudrate > topSpeeds[0 ] && baudrate <= topSpeeds[1 ])
488+ {
489+ speedBit = 1 ; // Fast mode+
490+ clockStretchMode = false ; // See: 28.6.2.4.6
491+ }
492+ else if (baudrate > topSpeeds[1 ])
493+ {
494+ speedBit = 2 ; // High speed
495+ clockStretchMode = true ; // See: 28.6.2.4.6
496+ }
497+ // else speedBit = 0 and clockStretchMode = false for Standard/Fast mode (up to 400kHz)
498+
499+ sercom->I2CM .CTRLA .bit .SPEED = speedBit;
500+ sercom->I2CM .CTRLA .bit .SCLSM = clockStretchMode; // See: 28.6.2.4.6
501+
502+ uint32_t minBaudrate = freqRef / 512 ; // BAUD = 255: SAMD51(@100MHz) ~195kHz, SAMD21 ~94kHz
503+ uint32_t maxBaudrate = topSpeeds[speedBit];
485504 baudrate = max (minBaudrate, min (baudrate, maxBaudrate));
486505
487506 if (speedBit == 0x2 )
488507 sercom->I2CM .BAUD .bit .HSBAUD = freqRef / (2 * baudrate) - 1 ;
489508 else
490- sercom->I2CM .BAUD .bit .BAUD = freqRef / (2 * baudrate) - 5 - freqRef * WIRE_RISE_TIME_NANOSECONDS / (2 * 1e9f);
509+ sercom->I2CM .BAUD .bit .BAUD = freqRef / (2 * baudrate) - 5 -
510+ (freqRef/1000000ul * WIRE_RISE_TIME_NANOSECONDS) / 2000 ;
491511}
492512
493513void SERCOM::prepareNackBitWIRE ( void )
@@ -543,7 +563,8 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
543563 }
544564
545565 // Send start and address
546- sercom->I2CM .ADDR .bit .ADDR = address;
566+ sercom->I2CM .ADDR .reg = SERCOM_I2CM_ADDR_ADDR (address) |
567+ ((sercom->I2CM .CTRLA .bit .SPEED == 0x2 ) ? SERCOM_I2CM_ADDR_HS : 0 );
547568
548569 // Address Transmitted
549570 if ( flag == WIRE_WRITE_FLAG ) // Write mode
0 commit comments