
Wolfgang Grandegger wg@grandegger.com wrote on 15/09/2009 13:53:13:
Joakim Tjernlund wrote:
Wolfgang Grandegger wrote:
I did not follow the thread yet, sorry. I implemented AN2819 for Linux (see http://lxr.linux.no/#linux+v2.6.31/drivers/i2c/busses/i2c-mpc.c) some time ago using Timur's table approach. But there is no difference between the table and the algorithm to calculate the value. The table is actually derived from the same algorithm.
The problem with the table is that it does not allow for flexibility in choosing dfsr. When I implemented the table code, I did not think that this was a problem, but apparently it is.
Yes, it is a problem for us as our board is out of spec. The rise time is way off spec. By trial and error with the DFSR/FDR I managed to get a stable connection. What is less funny though is that I need to program FDR/DFSR differently in u-boot resp. kernel. to make it work. I suspect it is due to kernel being IRQ driven and has longer pause between chars, but it is a guess.
In any case, the revised AN2819 dictates a different algorithm but I feel it is a bit incomplete w.r.t Condition 2:
• Condition 2: B × T ≥ tI2CRM + 3 × C × T.
Given a suitable value of DFSR, chosen to satisfy Condition 1, this
inequality must also be met to guarantee
that the SCL frequency matches the SCL frequency calculated by the divider
equation. It is important to
note that tI2CRM is the measured rise time of the SCL signal, which is
defined as the time for the signal to
rise from 10% to 70% of VCC.
NOTE Note that the rise time must not exceed 300 nanoseconds
and that the above
two conditions must both be satisfied to ensure that the actual SCL frequency values align with the calculated values. By meeting these conditions, the measured SCL frequency will match the calculated frequency to within 5 kHz. Ignoring either of these
conditions may result in
larger discrepancies between these frequency values.
How important is Condition 2 and what to do with rise times > 300 ns? The
MAX rise time
for 100 KHz is 1000 ns so there is a gap here.
My testing suggests that this is not important. Bigger DFSR, in my case 0x6
or 0x10, is key
to get a stable I2C bus.
Jocke
PS. Wolfgang, I sent a test program to calculate the new DFSR/FDR values in
the thread, you
might find it useful if you are going to try out the new AN2819
Where do I find this test program.
In this thread. Attached for you convenience.
I just dig out my program to calculate the table entries for the Linux i2c-mpc.c. It actually reproduced Timur's (old) U-Boot values. Unfortunately, finding *good* dfsr/fdr settings is no trivial and takes time.
That was what my program intends to do. Works quite well but isn't perfect(See attached file: fdr.c)
Till recently, the i2c-mpc driver of Linux did use *fixed* save values as shown here:
http://lxr.linux.no/#linux+v2.6.29/drivers/i2c/busses/i2c-mpc.c
And also with newer kernels, the table is only used if one of the following I2C DTS properties is defined:
- fsl,preserve-clocking;
ehh, I figured preserve-clocking meant use whatever fdr/dfsr is already set to.
- clock-frequency = <400000>;
See http://lxr.linux.no/#linux+v2.6.31/Documentation/powerpc/dts-bindings/fsl/i2...
I am using 2.6.30 and I think it is fairly equal to yours. I am not using either property above so the linux i2c-mpc. driver falls back to fdr=0x31 and dfsr=0x10 and this works well. It is u-boot that isn't working. However, I have found a few driver bugs in the u-boot driver and fixing those makes the fsl-i2c.c driver work well again.
You can easily stress test I2C in u-boot by entering date;date;date;date;date and then press and hold Enter for a while.
Jocke