Following on some discussion on another thread with racemaniac, I tested overclocking i2c1 up to 1.3Mhz successfully.
I was wondering if it would be of value adding the code to the core, perhaps limited down to 1Mhz.
This is OUT OF SPECS for the F1 i2c port. Official STM documents indicate up to 400Khz. But they also indicate SPI1 should run at no more than 18Mhz, and we routinely run it at 36Mhz and is allowed in the core, with most people probably not knowing 36Mhz is out of specs.
Should I submit the PR for this?
So I dont see a problem with allowing people to set arbitary higher or lower data rates if the hardware supports it.
If you need speed, spi is better, I think.
[dannyf – Fri Oct 06, 2017 11:36 pm] –
You can set thebi2c clock divider however you want. The key question is: are there i2c slaves fast enough to respond to that.
obviously the answer is yes ^^
victor used it for i2c memory which can handle those speeds, i used it for a popular i2c dac that can handle those speeds
.
i was also wondering how currently the speed is set. ideally it would be something easy (an enum you can use to set the speed, containing certain often used values (100khz, 400khz, 800khz_overclock, 1mhz_overclock) or something like that). not messing with dividers.
They communicate 100/400kHz (Standard/Fast Speed) from init(), but the High-Speed mode (up to 3.4MHz) needs to be activated (a command sent to the master).
It seems you have to be able to change the clock on-the-fly.
Wikipedia:
. In 1992, Version 1 added 400 kHz Fast-mode (Fm) and a 10-bit addressing mode to increase capacity to 1008 nodes. This was the first standardized version.
. In 1998, Version 2 added 3.4 MHz High-speed mode (Hs) with power-saving requirements for electric voltage and current.
. In 2000, Version 2.1 clarified version 2, without significant functional changes.
. In 2007, Version 3 added 1 MHz Fast-mode plus (Fm+) (using 20 mA drivers), and a device ID mechanism.
. In 2012, Version 4 added 5 MHz Ultra Fast-mode (UFm) for new USDA (data) and USCL (clock) lines using push-pull logic without pull-up resistors, and added an assigned manufacturer ID table. It is only a unidirectional bus.
You can look at the code of SetClock() to see what I mean.
[racemaniac – Sat Oct 07, 2017 5:52 am] –
i was also wondering how currently the speed is set. ideally it would be something easy (an enum you can use to set the speed, containing certain often used values (100khz, 400khz, 800khz_overclock, 1mhz_overclock) or something like that). not messing with dividers.
The wire class uses SetClock(), but our implementation only allows 100 and 400Khz. Then setclock calls a libmaple function, can’t remember the name, and that one doesn’t calculate all the right registers for other than 100 and 400. I added a new function in libmaple to calculate them for any overclocking speed, and modified SetClock() to call the new function when the speed is over 400Khz. I could integrate it in the existing libmaple function, but did it a separate one just for testing.
initialize the i2c module and then change the clock divider, like this:
void myI2C_init(int i2c_ps) {
I2C_init(); //stock i2c initialization
I2C_PS = i2c_ps; //set i2c clock divider based on parameter passed to myI2C_init() – figuratively speaking
}
so in the future, rather than calling I2C_init() to reset the module, use myI2C_init().
Im pretty sure I looked at the Due code and it supported other speeds – though just an expanded list of speed settings.
( I presumed perhaps the SAM architecture only had a liminted number of speeds which the hardware could operate at, because the API call accepts the frequency, and the code just finds the nearest available freq that the hardware supports. Either that or someone at Arduino just decided on those arbitary steps)
TWI_CWGR is only used in Master mode.
• CLDIV: Clock Low Divider
The SCL low period is defined as follows:
• CHDIV: Clock High Divider
The SCL high period is defined as follows:
• CKDIV: Clock Divider
The CKDIV is used to increase both SCL high and low periods
The formula are given as well.
you may also look into what sets Tmck.
[RogerClark – Sat Oct 07, 2017 9:14 pm] –
I think we should add this feature..Im pretty sure I looked at the Due code and it supported other speeds – though just an expanded list of speed settings.
( I presumed perhaps the SAM architecture only had a liminted number of speeds which the hardware could operate at, because the API call accepts the frequency, and the code just finds the nearest available freq that the hardware supports. Either that or someone at Arduino just decided on those arbitary steps)
The arduino API documents several other speeds (1Mhz, 3.4Mhz) but mentions that the user needs to check what’s supported in his hardware.
From my tests with FRAM I was able to realibly get up to 1.3Mhz, and Racemaniac was able to get around the same speed before having problems.
The peripheral can work at many different speeds with the right settings, but I understand the standard i2c speeds are only a few.
So we can take both paths, set only the standard speeds with an enum (100Khz, 400Khz, 1Mhz), or just allow any speed within the range. I wrote my code in the second form since I wanted to test how fast it could go beyong 400Khz.
For reference the DUE allows any speed and just calculates the register values that match the best, but imposes to limit:
https://github.com/arduino/ArduinoCore- … e.cpp#L140
https://github.com/arduino/ArduinoCore- … twi.c#L114
100kHz
400kHz
1MHz
MAX_FREQUENCYbest of both worlds.
