MCF52259 I2C I2FDR Incorrect clock frequency

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF52259 I2C I2FDR Incorrect clock frequency

Jump to solution
1,390 Views
WHookway
Contributor III

Hi,

 

I am using the I2C interface and have a strange clock frequency problem.  My system oscillator is 24 Mhz with a predivide (CCHR=2) divide by 3, and a PLL multiply by 8 for a system clock frequency of 64 Mhz.

 

Setting the I2FDR register with 0x0d (divide by 160) results in a slightly slow clock frequency of 381 KHz.  If I use the 0x30 (also divide by 160) I get the correct frequency of 400KHz.  Trying other values from the 2nd or 4th column of the I2FDR work as expected, but selecting the same divider from columns 1 and 3 result in a slightly slow frequency.

 

I cannot find any information on what the individual bits of the I2FDR register do.  Why are there multiple frequency dividers?

Any help would be appreciated.

 

Thanks,

Will

Labels (1)
0 Kudos
1 Solution
796 Views
TomE
Specialist II

I'm running similar tests on the I2C I2FDR in an MCF5329 and and getting similar baffling results.

 

> Why are there multiple frequency dividers?


Good question. The two tables (0x00 - 0x1F and 0x20 - 0x3F) seem to be slightly different attempts at "logorithmic curve fitting". One is based on "10, 12, 14, 16" and the other on "10, 12, 15, 18" (see below).

 

But why should they have those duplicate entries, and why are you seeing them not be duplicates? I'm measuring that as well.

 

The divider for "0x0e" is listed as 192, which with my 80MHz clock should give 416.66kHz, but I'm measuring 400kHz. That means it seems to be dividing by 200 instead of 192.

 

The divider 0x31 is listed to give 192, and with it I'm measuring 416.7kHz as expected.

 

More surprisingly, setting I2FDE to "0" should divide by 28, but I'm seeing 2.0MHz, meaning it is dividing by 40! But the signal is looking pretty bad so I've just put a 1k pullup resistor on SCL and the frequency increases to 2.425 MHz, or divide by 33.

 

With that 1k pullup on the SCL signal (in parallel with the 4.7k one already there) with an I2FDR value of 0x0E I get 416.7kHz, matching the table.

 

It all becomes clear. The I2FDR description includes the comment "Due to potentially slow I2C_SCL and I2C_SDA rise and fall times, bus signals are sampled at the prescaler frequency.". As well, I2C allows the slave device to extend the clock timing by clamping the clock to ground for as long as it likes. The Master has to monitor the SCL signal for this condition. With a large pullup and a slow rise time, the master is seeing the SCL signal being extended, and is slowing down the timing. It would also seem that "0x0E" and "0x31" use different prescalers, and 0x31 isn't extending the SCL timing on a slow rrise time whereas 0x0E is.

 

So put a smaller pullup on your SCL (and SDA) signals and you'll probably see the 0x0d and 0x30 ones giving the same result.

 

This divider is simple compared to the MPC chips. Read AN2919 for details on how the tables in those chips specify one divider giving ratios of 18, 20, 24, 30, 10, 12, 14 and 16 combined with another divider of 16, 32, 64, 128, 256, 512, 1024 and 2048, together with another divider and a factor of "3". I think the MCF I2FDR might be a simplified version of the MCP ones.

 

Yes, these are the division ratios, the repeating pattern (apart from the slightly weird low numbers) is pretty obvious when you look at it like this:

 

0x00   28  14 * 2  0x01   30  15 * 2  0x02   34  17 * 2  0x03   40  10 * 4  0x04   44  11 * 40x05   48  12 * 4  0x06   56  14 * 4  0x07   68  17 * 4  0x08   80  10 * 8  0x09   88  11 * 8  0x0A  104  13 * 8  0x0B  128  16 * 8  0x0C  144  18 * 8  0x0D  160  10 * 16 <-- All "10, 12, 15, 18" from here on down 0x0E  192  12 * 16 0x0F  240  15 * 16 0x10  288  18 * 16 0x11  320  10 * 32 0x12  384  12 * 32 0x13  480  15 * 32 0x14  576  18 * 32 0x15  640  10 * 64 0x16  768  12 * 64 0x17  960  15 * 64 0x18 1152  18 * 64 0x19 1280  10 * 1280x1A 1536  12 * 1280x1B 1920  15 * 1280x1C 2304  18 * 1280x1D 2560  10 * 2560x1E 3072  12 * 2560x1F 3840  15 * 256

0x20   20  10 * 2
0x21   22  11 * 2
0x22   24  12 * 2
0x23   26  13 * 2
0x24   28  14 * 2
0x25   32  16 * 2
0x26   36  18 * 2
0x27   40  10 * 4
0x28   48  12 * 4
0x29   56  14 * 4
0x2A   64  16 * 4
0x2B   72  18 * 4
0x2C   80  10 * 8 <-- All "10, 12, 14, 16" from here on down
0x2D   96  12 * 8
0x2E  112  14 * 8
0x2F  128  16 * 8
0x30  160  10 * 16
0x31  192  12 * 16
0x32  224  14 * 16
0x33  256  16 * 16
0x34  320  10 * 32
0x35  384  12 * 32
0x36  448  14 * 32
0x37  512  16 * 32
0x38  640  10 * 64
0x39  768  12 * 64
0x3A  896  14 * 64
0x3B 1024  16 * 64
0x3C 1280  10 * 128
0x3D 1536  12 * 128
0x3E 1792  14 * 128
0x3F 2048  16 * 128

 Tom

 

View solution in original post

0 Kudos
9 Replies
796 Views
WHookway
Contributor III

Tom,

 

Thanks again for looking into this. The 600 ohms was just for testing.  I had sent a note to the hardware team posting my findings and referenced this thread.  I also told them to check on the drive capability of the output.  I will select the high drive output if they wish to change the pull up values from what they have. 

 

I generally do the same searching for bit and pieces of keywords.  Thanks for your help.

 

I don't think changing the drive will help this situation since the bus is a wired "AND" and I believe the problem is with the rise time.  I do not think the slew rate would affect the result either although it would be interesting to know if the slew rate affects the turn off time of the open collector transistor.  I would suspect not.

 

Regards,

Will

 

0 Kudos
796 Views
WHookway
Contributor III

Tom,

 

Thanks Tom for your feedback.

 

All,

 

I'm interfacing to a serial EEPROM, AT24C128.  I added the 1K pull-up resistor in parallel to the 5K that was already there, didn't quite do the trick.  Went to 600 ohms and now I get the same (expected, 400Khz) result with either 0x0D or 0x30 as the divider.  Whish they had an app note for this particular part that explains the operation of the clock divider circuit, and the impact of the individual bits, what bits control the prescaler.

 

Regards,

Will

 

 

 

0 Kudos
796 Views
TomE
Specialist II

> Went to 600 ohms

 

You're way over the maximum ratings with that resistor so it may cause other effects. 3.3V / 600 ohms is 5.5mA.


That's over the Datasheet maximum for the MCF52259 pins, which is 5.0mA when set to high-drive and way over the 2.0mA spec when set to "low drive".

 

That's also way over the maximum specification for the AT24C128 which is 2.1mA. The lowest you can go and meet both chip specs is 1k5.

 

Yes, it would be nice if there were more details on the "prescaler" than the following note:

 

I2C clock rate. Prescales the clock for bit-rate selection. The serial bit clock frequency is equal to the internal bus clock divided by the divider shown below. Due to potentially slow I2Cn_SCL and I2Cn_SDA rise and fall times, bus signals are sampled at the prescaler frequency.

 

In the above we have mention of the "bus clock", the "serial bit clock" and mention of a "prescaler clock" which could mean anything. It could mean the clock into the prescaler, our of the prescaler, or more likely a clock somewhere between the two. Just like a UART, the bits have to be sampled at some multiple of the bit rate (UARTs usually sample at 16 times the bit rate). The difference between the two otherwise identical prescaler values indicates that 0x0D and 0x30 are using different sample rates.

 

Looking again at the tables I derived in my previous post, I'm suspecting that both tables use the same "binary dividers" (2, 4, 8, 16, 32..." for the same rows in each table to generate the sampling clock, and then divide that by an "integer value" to get the bit clock. Changing the values to match this theory, I'm guessing that "0x0E" is performing "16 * 12" whereas "0x31" is performing "32 * 6". That would mean that "0x0E" is sampling 12 times per bit while "0x31" samples 6 times per bit, and so I'd expect "0x0E" to be twice as sensitive to a slow rise time than "0x31" is. That theory matches what we've measured.

 

But it wouldn't have been too hard for Freescale to add another column to the tables detailing this - maybe they didn't think we'd want or need to know this implementation detail.

 

What I also usually do at this point is to start searching the whole of the Freescale site for keywords, and then read all the different manuals with chapters on the I2C part in the hope that one of them has this sort of information. I usually find they're all cut-and-paste copies of each other, but sometimes I get lucky. If all the MCF manuals are the same, the component might have been used in an MPC. MC68HC or MC9S part, and may be better documented there. This part with all 8-bit registers looks like it was designed for an 8-bit bus and an 8-bit CPU, otherwise why not simply give us a full 16-bit divider register?

 

Searching Freescale's Documentation / App Note page for "I2C" finds 268 documents, including AN2919 which is worth reading, as the I2C controllers in the MPC parts have two dividers - one for the "digital filter sampling clock" and a separate one for the bit clock. The part gives full programmability of the sampling and bit rate, and results in a horribly complex part that absolutely needs a 20 page App Note to describe how to use it.

 

You should also read the Reference Manual for the MC9S12XDP512 part, which has a different I2C controller in it. The I2C Divider in that part has an 8 bit register:

 

The bit clock generator is implemented as a prescale divider — IBC7:6, prescaled shift register — IBC5:3 select the prescaler divider and IBC2-0 select the shift register tap point. The IBC bits are decoded to give the tap and prescale values as shown in Table 9-3.

 

There are 7 pages of tables and diagrams showing all the options for working out which one of the 256 combinations in that register will result in something that works. There are lots of combinations that probably won't work.

 

So there's a balance between a "fully flexible" part that is very hard to program correctly (like the MPC and MC9S ones) and an "opaque" part (MCF) with a single weird table which is impossible to program illegally. After seeing the alternatives, I'm thinking that someone at Freescale made a good decision with the MCF I2C controller.

 

Tom

 

0 Kudos
796 Views
FridgeFreezer
Senior Contributor I

Crikey Tom, I wish I had your patience!

 

A question that's just popped into my mind is: Could this have anything to do with the pin drive strength & slew-rate registers?

0 Kudos
796 Views
FridgeFreezer
Senior Contributor I

Given the clock-stretching feature of I2C I'd hope a +/-5% deviation in SCK would not be worth worrying about, if it is then you want to run a fair bit faster.

0 Kudos
797 Views
TomE
Specialist II

I'm running similar tests on the I2C I2FDR in an MCF5329 and and getting similar baffling results.

 

> Why are there multiple frequency dividers?


Good question. The two tables (0x00 - 0x1F and 0x20 - 0x3F) seem to be slightly different attempts at "logorithmic curve fitting". One is based on "10, 12, 14, 16" and the other on "10, 12, 15, 18" (see below).

 

But why should they have those duplicate entries, and why are you seeing them not be duplicates? I'm measuring that as well.

 

The divider for "0x0e" is listed as 192, which with my 80MHz clock should give 416.66kHz, but I'm measuring 400kHz. That means it seems to be dividing by 200 instead of 192.

 

The divider 0x31 is listed to give 192, and with it I'm measuring 416.7kHz as expected.

 

More surprisingly, setting I2FDE to "0" should divide by 28, but I'm seeing 2.0MHz, meaning it is dividing by 40! But the signal is looking pretty bad so I've just put a 1k pullup resistor on SCL and the frequency increases to 2.425 MHz, or divide by 33.

 

With that 1k pullup on the SCL signal (in parallel with the 4.7k one already there) with an I2FDR value of 0x0E I get 416.7kHz, matching the table.

 

It all becomes clear. The I2FDR description includes the comment "Due to potentially slow I2C_SCL and I2C_SDA rise and fall times, bus signals are sampled at the prescaler frequency.". As well, I2C allows the slave device to extend the clock timing by clamping the clock to ground for as long as it likes. The Master has to monitor the SCL signal for this condition. With a large pullup and a slow rise time, the master is seeing the SCL signal being extended, and is slowing down the timing. It would also seem that "0x0E" and "0x31" use different prescalers, and 0x31 isn't extending the SCL timing on a slow rrise time whereas 0x0E is.

 

So put a smaller pullup on your SCL (and SDA) signals and you'll probably see the 0x0d and 0x30 ones giving the same result.

 

This divider is simple compared to the MPC chips. Read AN2919 for details on how the tables in those chips specify one divider giving ratios of 18, 20, 24, 30, 10, 12, 14 and 16 combined with another divider of 16, 32, 64, 128, 256, 512, 1024 and 2048, together with another divider and a factor of "3". I think the MCF I2FDR might be a simplified version of the MCP ones.

 

Yes, these are the division ratios, the repeating pattern (apart from the slightly weird low numbers) is pretty obvious when you look at it like this:

 

0x00   28  14 * 2  0x01   30  15 * 2  0x02   34  17 * 2  0x03   40  10 * 4  0x04   44  11 * 40x05   48  12 * 4  0x06   56  14 * 4  0x07   68  17 * 4  0x08   80  10 * 8  0x09   88  11 * 8  0x0A  104  13 * 8  0x0B  128  16 * 8  0x0C  144  18 * 8  0x0D  160  10 * 16 <-- All "10, 12, 15, 18" from here on down 0x0E  192  12 * 16 0x0F  240  15 * 16 0x10  288  18 * 16 0x11  320  10 * 32 0x12  384  12 * 32 0x13  480  15 * 32 0x14  576  18 * 32 0x15  640  10 * 64 0x16  768  12 * 64 0x17  960  15 * 64 0x18 1152  18 * 64 0x19 1280  10 * 1280x1A 1536  12 * 1280x1B 1920  15 * 1280x1C 2304  18 * 1280x1D 2560  10 * 2560x1E 3072  12 * 2560x1F 3840  15 * 256

0x20   20  10 * 2
0x21   22  11 * 2
0x22   24  12 * 2
0x23   26  13 * 2
0x24   28  14 * 2
0x25   32  16 * 2
0x26   36  18 * 2
0x27   40  10 * 4
0x28   48  12 * 4
0x29   56  14 * 4
0x2A   64  16 * 4
0x2B   72  18 * 4
0x2C   80  10 * 8 <-- All "10, 12, 14, 16" from here on down
0x2D   96  12 * 8
0x2E  112  14 * 8
0x2F  128  16 * 8
0x30  160  10 * 16
0x31  192  12 * 16
0x32  224  14 * 16
0x33  256  16 * 16
0x34  320  10 * 32
0x35  384  12 * 32
0x36  448  14 * 32
0x37  512  16 * 32
0x38  640  10 * 64
0x39  768  12 * 64
0x3A  896  14 * 64
0x3B 1024  16 * 64
0x3C 1280  10 * 128
0x3D 1536  12 * 128
0x3E 1792  14 * 128
0x3F 2048  16 * 128

 Tom

 

0 Kudos
796 Views
JimDon
Senior Contributor III

" With a large pullup and a slow rise time, the master is seeing the SCL signal being extended, and is slowing down the timing."

So when you put the smaller pull up, the clock rate changed?

 

0 Kudos
796 Views
TomE
Specialist II

> So when you put the smaller pull up, the clock rate changed?

 

Yes.

 

Summarising my post:

 

1 - Program to "/192" with 0x31 in I2FDR. Measure "/192" with 4k7 pullup.

 

2 - Program to "/192" with 0x0e in I2FDR. Measure "/200" with 4k7 pullup. Measure "/192" with 820 pullup (1k and 4k7).

 

3 - Program to "/28" with 0x00 in I2FDR. Measure "/40" with 4k7 pullup. Measure "/33" with 820 pullup.

 

That certainly looks like "clock stretch".

 

Tom

 

0 Kudos
796 Views
JimDon
Senior Contributor III

What I2C device are you testing it with?

0 Kudos