i2c works at 60mhz but not 48mhz

Started by tojomico October 27, 2006
Hi Group,

I have an LPC2214 chip for which I'm attempting to use the i2c bus.

If I run my board at 60 mhz (12 mhz oscillator * 5), i2c works fine.
When I reduce the speed to 48 mhz (12 mhz * 4), i2c no longer works.

All I do in order to break i2c is change the value of PLLCFG to 0x23
instead of 0x24 during startup. I've tried changing the values for
I2SCLH and I2SCLL to match the same time period under the new fclk
speed but it doesn't help any.

Basically whenever I try to read a value off the i2c bus at the lower
speed, I get back 0x48 instead of the proper value.

Anyone know what other registers I should be modifying to get i2c to
work at the lower speed? I keep vpbdiv constant at 1 in either case
if that matters.

Thanks,
Tom

An Engineer's Guide to the LPC2100 Series

--- In l..., "tojomico" wrote:
>
> Hi Group,
>
> I have an LPC2214 chip for which I'm attempting to use the i2c bus.
>
> If I run my board at 60 mhz (12 mhz oscillator * 5), i2c works fine.
> When I reduce the speed to 48 mhz (12 mhz * 4), i2c no longer works.
>
> All I do in order to break i2c is change the value of PLLCFG to 0x23
> instead of 0x24 during startup. I've tried changing the values for
> I2SCLH and I2SCLL to match the same time period under the new fclk
> speed but it doesn't help any.
>
> Basically whenever I try to read a value off the i2c bus at the lower
> speed, I get back 0x48 instead of the proper value.
>
> Anyone know what other registers I should be modifying to get i2c to
> work at the lower speed? I keep vpbdiv constant at 1 in either case
> if that matters.
>
> Thanks,
> Tom
>

Hi Tom,

a long shot but who knows... Is it possible that your CPU is heavily
loaded or has some higher priority interrupts that take a long time to
execute?
If so, it is possible that your CPU just does not have the bandwidth
or the required time slots to get the data from the I2C.
You could try, just for fun, to assign the FIQ to the I2C routine. If
it starts to work now, you either have a priority issue in your setup
or a performance issue at 48 MHz.

May be it helps, Bob
It's hard to believe.

Here are a few things to check:

The combination of I2CLKL and I2CLKH should be greater
than approx. 140 in order to obtain the I2C clock less then
400K. Make the duty 50/50 or CLKL value equals to CLKH.

What's the value you set for CLKL and CLKH?
What the actual I2C clock showing on the scope?
What's the max I2C clock allowed on the I2C device?

Tom

--- In l..., "lpc2100_fan"
wrote:
>
> --- In l..., "tojomico"
wrote:
> >
> > Hi Group,
> >
> > I have an LPC2214 chip for which I'm attempting to use the i2c
bus.
> >
> > If I run my board at 60 mhz (12 mhz oscillator * 5), i2c works
fine.
> > When I reduce the speed to 48 mhz (12 mhz * 4), i2c no longer
works.
> >
> > All I do in order to break i2c is change the value of PLLCFG to
0x23
> > instead of 0x24 during startup. I've tried changing the values
for
> > I2SCLH and I2SCLL to match the same time period under the new
fclk
> > speed but it doesn't help any.
> >
> > Basically whenever I try to read a value off the i2c bus at the
lower
> > speed, I get back 0x48 instead of the proper value.
> >
> > Anyone know what other registers I should be modifying to get
i2c to
> > work at the lower speed? I keep vpbdiv constant at 1 in either
case
> > if that matters.
> >
> > Thanks,
> > Tom
> > Hi Tom,
>
> a long shot but who knows... Is it possible that your CPU is
heavily
> loaded or has some higher priority interrupts that take a long
time to
> execute?
> If so, it is possible that your CPU just does not have the
bandwidth
> or the required time slots to get the data from the I2C.
> You could try, just for fun, to assign the FIQ to the I2C routine.
If
> it starts to work now, you either have a priority issue in your
setup
> or a performance issue at 48 MHz.
>
> May be it helps, Bob
>
--- In l..., "tojomico" wrote:
>
> Hi Group,
>
> I have an LPC2214 chip for which I'm attempting to use the i2c bus.
>
> If I run my board at 60 mhz (12 mhz oscillator * 5), i2c works fine.
> When I reduce the speed to 48 mhz (12 mhz * 4), i2c no longer works.
>
> All I do in order to break i2c is change the value of PLLCFG to 0x23
> instead of 0x24 during startup. I've tried changing the values for
> I2SCLH and I2SCLL to match the same time period under the new fclk
> speed but it doesn't help any.
>
> Basically whenever I try to read a value off the i2c bus at the lower
> speed, I get back 0x48 instead of the proper value.
>
> Anyone know what other registers I should be modifying to get i2c to
> work at the lower speed? I keep vpbdiv constant at 1 in either case
> if that matters.
>
> Thanks,
> Tom

Hi Tom,

Try running the I2C bus at standard clock rate of 100 KHz.

The timing relationships when running at different speeds are
non-trivial considering what you see when you put a probe on the clock
or data signal line is the interaction of all devices on the bus, not
just the master and the addressed slave.

If you are having problems at 48 MHz, but not at 60 MHz when running
prim and proper at standard rate, please get in touch with me by email.

Regards,

Jaya
Hi Group,

Thanks for the responses. Sorry it's been a couple days since your
replies but I'll try to fill in the details as best I can.

Re: interrupts - the application I'm using is a little test app
written in C that runs on top of the metal - no interrupts are enabled
or are just stubs, so I don't think that is the problem.

The original values (that work at 60mhz) for I2CLKL/I2CLKH are 80
each. I didn't come up with these values, the code came as a sample
for the board from the group responsible for developing it.
- if I leave these values at 80 and just switch the clock rate to
48mhz then whenever I request data off the I2C bus it returns 0x48.
- if I change the values to keep the same freq / (I2CLKL+I2CLKH)
ratio, I'm changing the I2CLKL/H values to be 64. In this event I get
the same response of 0x48 from the bus.

I realize that that's pretty fast, so here's my results at 48mhz clock
/ 100khz bus (as recommended by jayasooriah).

100khz bus at 48mhz gives a sum of 480 for I2CLKL + I2CLKH so I'll set
both at 240 for 50/50 duty.

Result? I still get 0x48 for all returns on the bus.

For comparison, if I set the clock to 60mhz, then set I2CLKL and
I2CLKH at 300 each (100khz), my result is.. the bus works.

Unfortunately I don't have a scope so I cannot detect what is going on
at that level.

Anyone have any ideas?

Cheers,
Tom Burns
--- In l..., "lpc2100_fan" wrote:
>
> --- In l..., "tojomico" wrote:
> >
> > Hi Group,
> >
> > I have an LPC2214 chip for which I'm attempting to use the i2c bus.
> >
> > If I run my board at 60 mhz (12 mhz oscillator * 5), i2c works fine.
> > When I reduce the speed to 48 mhz (12 mhz * 4), i2c no longer works.
> >
> > All I do in order to break i2c is change the value of PLLCFG to 0x23
> > instead of 0x24 during startup. I've tried changing the values for
> > I2SCLH and I2SCLL to match the same time period under the new fclk
> > speed but it doesn't help any.
> >
> > Basically whenever I try to read a value off the i2c bus at the lower
> > speed, I get back 0x48 instead of the proper value.
> >
> > Anyone know what other registers I should be modifying to get i2c to
> > work at the lower speed? I keep vpbdiv constant at 1 in either case
> > if that matters.
> >
> > Thanks,
> > Tom
> > Hi Tom,
>
> a long shot but who knows... Is it possible that your CPU is heavily
> loaded or has some higher priority interrupts that take a long time to
> execute?
> If so, it is possible that your CPU just does not have the bandwidth
> or the required time slots to get the data from the I2C.
> You could try, just for fun, to assign the FIQ to the I2C routine. If
> it starts to work now, you either have a priority issue in your setup
> or a performance issue at 48 MHz.
>
> May be it helps, Bob
>
Hi Tom,

You say you're always getting 0x48 from the bus.
What precisely do you mean by that?
Is that the value that appears in I2CDAT when you
expect the read to have completed?
What is the value in I2CSTAT immediately before you
read I2CDAT ?

I guess you're polling the I2C hardware since you say
that no interrupts are running. From what I understand,
the peripherals do not "like" being polled because you
get simultaneous accesses of the status register from
both the hardware and the processor.
Having a debugger watch the peripheral can also cause problems.

One thing you might try is to poll the appropriate bit
in VICRawIntr to see if the I2C peripheral is requesting
an interrupt - and only look at I2CSTAT once that is
asserted. This sort of trick is only needed while you're
polling - once you have interrupts going things work fine.

And if you get really paranoid, try bit-banging the
I2C bus. This will really tell you what is going on
even without a 'scope.

Hope this helps,
Danish