From 3cc0846d78f04a0dcff91b7b465d165dc3ad06ac Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Mon, 8 Aug 2022 21:17:42 +0200 Subject: [PATCH 1/3] Fix #105 - make setspeed more robust - prevent out of range I2C speeds for AVR --- Adafruit_I2CDevice.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Adafruit_I2CDevice.cpp b/Adafruit_I2CDevice.cpp index 70f45b3..15c5149 100644 --- a/Adafruit_I2CDevice.cpp +++ b/Adafruit_I2CDevice.cpp @@ -264,33 +264,43 @@ bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) { #if defined(__AVR_ATmega328__) || \ defined(__AVR_ATmega328P__) // fix arduino core set clock // calculate TWBR correctly - uint8_t prescaler = 1; + + if ((F_CPU / 18) < desiredclk) { + #ifdef DEBUG_SERIAL + Serial.println(F("I2C.setSpeed too high.")); + #endif + return false; + } uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2; + if (atwbr > 16320) { + #ifdef DEBUG_SERIAL + Serial.println(F("I2C.setSpeed too low.")); + #endif + return false; + } + if (atwbr <= 255) { - prescaler = 1; + atwbr /= 1; TWSR = 0x0; } else if (atwbr <= 1020) { atwbr /= 4; - prescaler = 4; TWSR = 0x1; } else if (atwbr <= 4080) { atwbr /= 16; - prescaler = 16; TWSR = 0x2; - } else if (atwbr <= 16320) { + } else { // if (atwbr <= 16320) atwbr /= 64; - prescaler = 64; TWSR = 0x3; } + TWBR = atwb; + #ifdef DEBUG_SERIAL Serial.print(F("TWSR prescaler = ")); - Serial.println(prescaler); + Serial.println(pow(4, TWSR)); Serial.print(F("TWBR = ")); Serial.println(atwbr); #endif - TWBR = atwbr; return true; - #elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \ !defined(TinyWireM_h) _wire->setClock(desiredclk); From e2388229218af89c5ee5022496b335cebbf60c19 Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Mon, 8 Aug 2022 21:31:17 +0200 Subject: [PATCH 2/3] clang-format --- Adafruit_I2CDevice.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Adafruit_I2CDevice.cpp b/Adafruit_I2CDevice.cpp index 15c5149..5ec8c7e 100644 --- a/Adafruit_I2CDevice.cpp +++ b/Adafruit_I2CDevice.cpp @@ -266,19 +266,19 @@ bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) { // calculate TWBR correctly if ((F_CPU / 18) < desiredclk) { - #ifdef DEBUG_SERIAL +#ifdef DEBUG_SERIAL Serial.println(F("I2C.setSpeed too high.")); - #endif +#endif return false; } uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2; if (atwbr > 16320) { - #ifdef DEBUG_SERIAL +#ifdef DEBUG_SERIAL Serial.println(F("I2C.setSpeed too low.")); - #endif +#endif return false; } - + if (atwbr <= 255) { atwbr /= 1; TWSR = 0x0; @@ -288,7 +288,7 @@ bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) { } else if (atwbr <= 4080) { atwbr /= 16; TWSR = 0x2; - } else { // if (atwbr <= 16320) + } else { // if (atwbr <= 16320) atwbr /= 64; TWSR = 0x3; } From 319d44c093127d79ab59f585e33a5a0e1224f0ef Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Mon, 8 Aug 2022 22:02:39 +0200 Subject: [PATCH 3/3] fix build --- Adafruit_I2CDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_I2CDevice.cpp b/Adafruit_I2CDevice.cpp index 5ec8c7e..9b518b4 100644 --- a/Adafruit_I2CDevice.cpp +++ b/Adafruit_I2CDevice.cpp @@ -292,7 +292,7 @@ bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) { atwbr /= 64; TWSR = 0x3; } - TWBR = atwb; + TWBR = atwbr; #ifdef DEBUG_SERIAL Serial.print(F("TWSR prescaler = "));