Timur Tabi <ti...@freescale.com> wrote on 10/09/2009 18:13:03: > > Joakim Tjernlund wrote: > > > This calculation does not seem to match AN2919. > > When I wrote the code, AN2919 was much smaller than what you have today. > > > Suppose one used only Table 7(almost what we have if you exclude dfsr!= 1) > > Table 7 is valid for 1 <= dfsr <=5 so how about replacing the current dfsr > > with: > > #ifdef __PPC__ > > u8 dfsr; > > dfsr = (5*(i2c_clk/1000))/(100000); > > if (dfsr > 5) > > dfsr = 5; > > if (!dfsr) > > dfsr = 1; > > debug("i2c_clk:%d, dfsr:%d\n", i2c_clk, dfsr); > > writeb(dfsr, &dev->dfsrr); /* set default filter */ > > #endif > > The value of FDR is dependent on the value of DFSR, so if I calculate DFSR, I > have to also calculate FDR. This means the table goes away. I'm okay with > that (since my table is no longer a viable approach, it seems), but it's more > work than I'm willing to do at the moment. Especically since this is going to > need a lot of testing before I'm willing to push it.
I could not resist so I did a quick start: #include <stdlib.h> #include <stdio.h> #define I2C_CLK 133332000 int main(int argc, char *argv[]) { unsigned long A,B,C; unsigned long divisor, req_div; unsigned long curr_div = ~0; unsigned long speed; if (argc != 2) { printf("%s <speed in HZ>\n", argv[0]); exit(1); } speed = atol(argv[1]); req_div = I2C_CLK/speed; C = (5*(I2C_CLK/1000))/(100000); if (!C) C = 1; for(A=10;A <= 30; A+=2) { for (B=16; B<=2048;B*=2) { divisor = B * (A + (3*C/B)*2); if (divisor > req_div && divisor < curr_div) { printf("div:%d, A:%d, B:%d\n", divisor, A, B); curr_div = divisor; } } if (A == 20) A+=2; if (A == 24) A+=4; } printf("\nreq_div:%d, curr_div:%d, DFSR:%d\n", req_div, curr_div, C); } This should be useful I hope. The special treatment for A == 20 and A == 24 is a bit strange though, do they really jump like that? Jocke _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot