LPC15xx I2C timing slightly different than described in the manual?

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC15xx I2C timing slightly different than described in the manual?

678 Views
volkeroth
Contributor II

I implemented an I2C driver for the LPC1549 and was puzzled to see that the timing is not quite as expected.
I'm using a clock frequency of 72MHz and an I2C clock divider of 18 (so I write the value 17 to CLKDIV) so the I2C peripheral clock is 4MHz.
According to the manual, writing 0x33 to MSTTIME should result in 5 clock ticks high (1.25µs), 5 clock ticks low (1.25µs) and a clock frequency of 400kHz (2.5µs period).
That is not the case though. The resulting frequency is 363.72kHz because the low period is 1.49µs (well, considering the slew rate probably more like 1.5µs) instead of 1.25µs.
So obviously a value of 3 in MSTSCLLOW doesn't lead to 5 clock ticks (1.25µs @4MHz) as the manual says but to 6 clock ticks (1.5µs @ 4MHz).
When I change my code to assume that the value written to MSTSCLLOW is actually three (instead of two) ticks lower than what the peripheral uses, I get a perfect 400kHz.
So is this a mistake in the manual???

Labels (1)
Tags (2)
0 Kudos
8 Replies

141 Views
houe
Contributor I

I am seeing a very similar issue. I am using an lpc824 micro but it looks like it shares the same i2c peripheral. I run the micro at system clock at 30MHz. This means I need 75 clocks per bit to realize a 400kHz clock. I'm configured the i2c module in 2 different ways (either divide 30MHz by 5 then use 15 clocks or divide 30MHz by 15 and then use 5 clocks) - one worked as expected but the other did not.

       //why does this produce 353khz?

       LPC_I2C->CLKDIV = 5 - 1;

       uint32_t sclH = 7;

       uint32_t sclL = 8;

       LPC_I2C->MSTTIME = (((sclH - 2) & 0x07) << 4) | ((sclL - 2) & 0x07);

The above code produced 353kHz (why!?!?), but if I change sclH to 6 and sclL to 7 then it generates 400khz exactly. But this doesn’t make sense based on the user manual documentation.I would have expected something like 462kHz.

 

Another way I’ve generated a 400khz clock is as follows:

      LPC_I2C->CLKDIV = 15 - 1;

       uint32_t sclH = 2;

       uint32_t sclL = 3;

       LPC_I2C->MSTTIME = (((sclH - 2) & 0x07) << 4) | ((sclL - 2) & 0x07);

This make sense and seems to operate as I would expect.

 

So my question is why did the settings from the first code snippet not generate 400khz clock? Am I violating some clocking requirements (I didn’t notice anything in the datasheet). What am I missing here? If you need additional code to analyze I can provide this.

0 Kudos

141 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hi Michael and Volker,

We have investigated about this behavior and noticed that in general when the divided clock to the I2C block is <= 2MHz the generated clock is accurate. So please write suitable value into LPC_I2C->CLKDIV and make sure the I2C block clock frequency is <=2MHz.

Hope it helps!

Best Regards,
Carlos Mendoza
Technical Support Engineer

0 Kudos

141 Views
ckphua
NXP Employee
NXP Employee

The issue here is 

The min tlow = 1.3uS => if you set MSTSCLOW =MSTSCLHIGH= 5 , you get tlow= 1.25uS 

So when you increase MSTSCLOW by 1 to 6, and I assume you also reduce MSTSCLHIGH =4, you get tlow =1.5uS (and t high = 1uS).... giving the frequency of 400kHz.

Is this what you are seeing?

0 Kudos

141 Views
volkeroth
Contributor II

No, as I initially explained: If I configure MSTTIME to 0x33, I should get 5 clock ticks low and 5 clock ticks high according to the manual, but instead I get 6 clock ticks low and 5 clock ticks high. That's what my scope shot shows: the period is too long by one 4MHz clock tick and the duty cycle is not symmetrical.

Now if I configure MSTSCLOW to 2 instead of 3 and leave MSTSCLHIGH at 3, I should get 4 clock ticks low and 5 clock ticks high, but I get 5 clock ticks low and 5 clock ticks low, resulting in exactly 400kHz.

So that 1.3µs guaranteed minimum has no influence whatsoever on my observation. And again: I didn't even aim at a 50% DC. My initial 400kHz DC setup was (and still is) 36%, but the limited resolution of the lo/hi time doesn't really allow that on the 15xx (more like 40%). As explained before, I just used the 50% for trouble shooting and to document the different behavior of t_low and t_high with the same configuration.

Anyway, even if this minimum guaranteed low time would actually extend the low period (which, as far as I recall wasn't the case in my measurements) , this would only change the DC, not the frequency. Well, unless you suggest some physical slew rate pad behavior would somehow influence the internal timing of the I2C peripheral.  So this is where this while data sheet idea crumbles to dust. IMHO the only sensible explanation for a wrong frequency (and let's mention again that it's off by exactly one I2C peripheral clock tick) is that the manual doesn't fit the I2C implementation for the 15xx.

0 Kudos

141 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hi Volker,

Maybe the behavior you mention happens because the pullup resistor is increasing the amount of time it takes for the clock to rise again. Could you share a screenshot of your clock signal?

Thanks in advance for your response!

Best Regards,
Carlos Mendoza
Technical Support Engineer

0 Kudos

141 Views
volkeroth
Contributor II

Well, asymmetrical slew rates can affect the duty cycle of course, but not the frequency.

So, yeah, if only the DC was off a little bit but the frequency was OK, I wouldn't assume an error in the manual.

Then again, the frequency is off by more or less exactly one clock cycle and that is more than suspicious.

Besides, even taking into account the asymmetrical  slew rates, this clearly isn't a 50% duty cycle.

SCR12.PNG

And again, after decreasing the low period by one more cycle (in contradiction to the manual), I get a perfect 400kHz.

0 Kudos

141 Views
DavidS
NXP Employee
NXP Employee

Hi Volker Oth,

I'm not I2C expert but have played with it recently.  The i2C clock is not 50% duty cycle per I2C Spec and what is in the LPC15xx Data Sheet as follows:

pastedImage_1.png

The tLOW and tHIGH are not the same.

With respect to the 400kHz on other architectures I have set for 400kHz and only received 376kHz (randomly type number as example) due to system clock chain and dividers used on I2C module.  If I changed I could get above 400kHz but then that would violate speed for slave device so left it <400kHz to allow system to operate successfully.

Regards,

David 

0 Kudos

141 Views
volkeroth
Contributor II

I fail to see how guaranteed minimum values from the data sheet would explain that the frequency is wrong when I set up the timing according to the manual. And it's not like 400kHz are not possible or I insist on a 50% DC. Actually I don't use 50% DC for 400kHz but the 50% case was just to show the problem more clearly. And as stated before, 400kHz are easily possible with 72MHz system clock and 4MHz I2C peripheral clock.
Again, the manual describes the MSTSCLLOW and MSTSCLHIGH fields in the I2C master time register MSTTIME identically, but they don't behave identically. IMHO the description of MSTSCLLOW is wrong and no minimum timing from the datasheet can convince me that this isn't the case.

0 Kudos