Skip to content

I2C clock cannot go below 30MHz as prescaler is not calculated #495

Open
@ladyada

Description

@ladyada

https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/Wire/src/utility/twi.c#L139
doesn't calculate/change the TWSR prescaler, which means that we can't get below approx 16mhz / 255*2 = 30KHz
i'm happy to submit a PR, would look like this (TWSR is write-only on the two lowest bits)

  // calculate TWBR correctly
  uint8_t prescaler = 1;
  uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
  if (atwbr <= 255) {
    prescaler = 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) {
    atwbr /= 64;
    prescaler = 64;
    TWSR = 0x3;
  }
  TWBR = atwbr;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions