Skip to content

Enable user to change the I2C clock frequency by calling setClock in the Wire library #1912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 2, 2014

Conversation

Lauszus
Copy link
Contributor

@Lauszus Lauszus commented Mar 6, 2014

@matthijskooijman
Copy link
Collaborator

Code looks good. There are few whitespace changes in there that I'd rather see in a separate commit, but that's just a nitpick.

I like using "setClock", since that is the same as the proposed "SPI.setClock" method.

@Lauszus
Copy link
Contributor Author

Lauszus commented Mar 7, 2014

I can put it into a separate commit if you like. There is some other whitespaces I can remove as well ;)

@Lauszus
Copy link
Contributor Author

Lauszus commented Jul 2, 2014

@cmaglie is there any chance this could get merged before the release of 1.5.7? The same goes for my other pull request: #2148. I would really appreciate if you could take a look at it. I can backport this to 1.0.6 if you like as well.

cmaglie added a commit that referenced this pull request Jul 2, 2014
Enable user to change the I2C clock frequency by calling setClock in the Wire library
@cmaglie cmaglie merged commit 49ec540 into arduino:ide-1.5.x Jul 2, 2014
@cmaglie
Copy link
Member

cmaglie commented Jul 2, 2014

Thanks!
Any chance to have an implementation for the Due too?

@Lauszus
Copy link
Contributor Author

Lauszus commented Jul 2, 2014

Here you go: #2157 ;)

@Lauszus Lauszus deleted the issues440 branch July 2, 2014 17:49
@mikaelpatel
Copy link

Short comment on this. First the idea is great and I have played around with this in Cosa, https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/TWI.hh#L291.

There is a slight difference compared to SPI. The TWI setting is (should be) for the bus while for SPI it is per device.

It is important to point out (in documentation) that it is the slowest device on the TWI bus that defines the setting and that it is not possible to dynamically adjust it, e.g., throttle-up for a faster device.

In Cosa the bus clock frequency (select) is given as a parameter to the SPI::Driver constructor and is per device driver, https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/SPI.hh#L90. For TWI, twi.set_freq() should be called before twi.begin() and the setting is for the bus driver (not per device). Actually there is also an SPI::Driver::set_clock() in Cosa as some SPI devices do want to throttle-up (e.g. SD device driver).

Cheers!

Ref. http://www.picaxeforum.co.uk/showthread.php?8535-i2c-Speeds&p=57327&viewfull=1#post57327

@PaulStoffregen
Copy link
Contributor

If the user attempts to set a speed faster than 1000000, this arithmetic results in a negative number, which results in an extremely slow speed. Perhaps the code should check for the maximum and prevent wrong results?

@cmaglie
Copy link
Member

cmaglie commented Jul 5, 2014

The datasheet says:

TWBR should be 10 or higher if the TWI operates in Master mode. If TWBR is lower than 10, the
Master may produce an incorrect output on SDA and SCL for the reminder of the byte. The prob-
lem occurs when operating the TWI in Master mode, sending Start + SLA + R/W to a Slave (a
Slave does not need to be connected to the bus for the condition to happen).

so the maximum allowed frequency is with TWBR==10 that generate a speed of F=16M/(16+10*2)=444444Hz

The setClock method should be rewritten as:

void TwoWire::setClock(uint32_t frequency)
{
  uint32_t max = F_CPU / (16 + 2*10);
  if (frequency > max)
    TWBR = 10; // Run at max speed
  else
    TWBR = ((F_CPU / frequency) - 16) / 2;
}

do you agree?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants