Skip to content

Commit 23ac286

Browse files
authored
Merge pull request #104 from adafruit/fixavrsetspeed
manually handle AVR i2c setspeed to handle slow clocks
2 parents c421326 + 3e0e740 commit 23ac286

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

Adafruit_I2CDevice.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,40 @@ uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
259259
* Not necessarily that the speed was achieved!
260260
*/
261261
bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
262-
#if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && !defined(TinyWireM_h)
262+
#if defined(__AVR__) // fix arduino core set clock
263+
// calculate TWBR correctly
264+
uint8_t prescaler = 1;
265+
uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
266+
if (atwbr <= 255) {
267+
prescaler = 1;
268+
TWSR = 0x0;
269+
} else if (atwbr <= 1020) {
270+
atwbr /= 4;
271+
prescaler = 4;
272+
TWSR = 0x1;
273+
} else if (atwbr <= 4080) {
274+
atwbr /= 16;
275+
prescaler = 16;
276+
TWSR = 0x2;
277+
} else if (atwbr <= 16320) {
278+
atwbr /= 64;
279+
prescaler = 64;
280+
TWSR = 0x3;
281+
}
282+
#ifdef DEBUG_SERIAL
283+
Serial.print(F("TWSR prescaler = "));
284+
Serial.println(prescaler);
285+
Serial.print(F("TWBR = "));
286+
Serial.println(atwbr);
287+
#endif
288+
TWBR = atwbr;
289+
return true;
290+
291+
#elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \
292+
!defined(TinyWireM_h)
263293
_wire->setClock(desiredclk);
264294
return true;
295+
265296
#else
266297
(void)desiredclk;
267298
return false;

0 commit comments

Comments
 (0)