
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. 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. 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; - clock-frequency = <400000>;
See http://lxr.linux.no/#linux+v2.6.31/Documentation/powerpc/dts-bindings/fsl/i2...
Wolfgang.