Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Is there a way to slow down the I2C datarate on a Teensy 3.0?

  1. #1
    Member dlchambers's Avatar
    Join Date
    Nov 2012
    Location
    Elkins, NH
    Posts
    45

    Is there a way to slow down the I2C datarate on a Teensy 3.0?

    I have a flaky I2C connection and I'm suspecting that it might be affected by the datarate.

    I'm running it as a Teesnyduino.

    Is there any way to slow down the I2C speed to a rate of my choosing, say 1kHz?

    And, while we're on the subject, what is the Teensy 3.0's I2C datarate when running in 96MHz overclock using the std Arduino Wire library?

    many thanks,
    -Dave

  2. #2
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    "suspecting" is not a very good method of determining what the actual poblem is, particularly if you're sitting on this side of the keyoard. Not enough info ;-)

    Do you have proper pull-up resistors installed ?
    How long is your connection and what cable are you using ?

    The "standard" I2C bus frequency is 100KHz with the wire library. You can usually lower that, but I strongly suggest you figure out what the electrical problem is. How did you determine that you have a "flaky" I2C connection ? What are the syptoms ?

    Perhaps also post what components you are trying to connect (schematics, link to data sheet etc.)

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,553
    Quote Originally Posted by dlchambers View Post
    I have a flaky I2C connection and I'm suspecting that it might be affected by the datarate.
    Yes, but you'll need to edit the Wire library code.

    Look for this code in Wire.cpp:

    Code:
    #if F_BUS == 48000000
            I2C0_F = 0x27;  // 100 kHz
            // I2C0_F = 0x1A; // 400 kHz
            // I2C0_F = 0x0D; // 1 MHz
            I2C0_FLT = 4;
    #elif F_BUS == 24000000
            I2C0_F = 0x1F; // 100 kHz
            // I2C0_F = 0x45; // 400 kHz
            // I2C0_F = 0x02; // 1 MHz
            I2C0_FLT = 2;
    #else
    #error "F_BUS must be 48 MHz or 24 MHz"
    #endif
    Those magic numbers from from table 44.4.1.10 on page 1027-1028 in the reference manual. 0x3F is the slowest, which should result in a 12.5 kHz clock on SCL.

    You can also use 0x7F or 0xBF, which turns on the multiplier, that should give you 6.25 or 3.125 kHz. However, I do not recommend using the multiplier. It seems to cause trouble with some of the I2C features.

    You can also run Teensy3 at 24 MHz to cut the bus clock speed in half.


    And, while we're on the subject, what is the Teensy 3.0's I2C datarate when running in 96MHz overclock using the std Arduino Wire library?
    It's 100 kHz.

    Internally, Teensy3 has several clocks. The "bus" clock is 48 MHz when the CPU is either 48 or 96. The I2C runs from the bus clock.

  4. #4
    Member dlchambers's Avatar
    Join Date
    Nov 2012
    Location
    Elkins, NH
    Posts
    45
    Do I also need to tweak the inline TWBRemulation functions in Wire.h?
    They're for __MK20DX128__, which IIRC is the Teensy 3.0

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,553
    Quote Originally Posted by dlchambers View Post
    Do I also need to tweak the inline TWBRemulation functions in Wire.h?
    Only if your code writes to TWBR.

  6. #6
    Senior Member
    Join Date
    May 2015
    Posts
    381
    Quote Originally Posted by PaulStoffregen View Post
    Yes, but you'll need to edit the Wire library code.

    Look for this code in Wire.cpp:

    Code:
    #if F_BUS == 48000000
            I2C0_F = 0x27;  // 100 kHz
            // I2C0_F = 0x1A; // 400 kHz
            // I2C0_F = 0x0D; // 1 MHz
            I2C0_FLT = 4;
    #elif F_BUS == 24000000
            I2C0_F = 0x1F; // 100 kHz
            // I2C0_F = 0x45; // 400 kHz
            // I2C0_F = 0x02; // 1 MHz
            I2C0_FLT = 2;
    #else
    #error "F_BUS must be 48 MHz or 24 MHz"
    #endif
    Those magic numbers from from table 44.4.1.10 on page 1027-1028 in the reference manual. 0x3F is the slowest, which should result in a 12.5 kHz clock on SCL.

    You can also use 0x7F or 0xBF, which turns on the multiplier, that should give you 6.25 or 3.125 kHz. However, I do not recommend using the multiplier. It seems to cause trouble with some of the I2C features.

    You can also run Teensy3 at 24 MHz to cut the bus clock speed in half.




    It's 100 kHz.

    Internally, Teensy3 has several clocks. The "bus" clock is 48 MHz when the CPU is either 48 or 96. The I2C runs from the bus clock.


    Paul can you verify this has changed to be lines in WireKinetis.cpp now?

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,553
    Yes, the Wire lib changed.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •