iMX28 I2C 400kHz clock settings

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

iMX28 I2C 400kHz clock settings

Jump to solution
9,993 Views
Matt_
Contributor II

Hello,

I've just been scoping the I2C clock line on my board and have noticed the following.

If HW_I2C_TIMING0 and HW_I2C_TIMING1 are set to 0x000f0007 and 0x001f000f for 400kHz operation as per page 1756 of the reference manual then the clock rate is 436kHz.

After reading the description I tried 0x0018000c in HW_I2C_TIMING0 to get a 1us clock high time, i.e. 24 clocks of 24MHz.  I put 0x00240010 in HW_I2C_TIMING1 to get 1.5us clock low.  2.5us -> 400kHz.

Unfortunately this gave me 348kHz.

Trial and error gave me 400kHz by putting the following values in the registers:

0x0010000c -> HW_I2C_TIMING0 which scopes out as 1us clock high.

0x00230010 -> HW_I2C_TIMING1 which scopes out as 1.5us clock low.

Hope this is helpful.

Matt.

Labels (1)
Tags (1)
0 Kudos
1 Solution
8,105 Views
JackyAtFreescal
Senior Contributor II

Hi Matt,

If no more issue, we will close this thread.

Regards,

Jacky

View solution in original post

0 Kudos
14 Replies
8,105 Views
srinivasanshanm
Contributor III

Hi Matthew,

Thanks a lot for your quick response, its really helpful your guidance for the guys who stuck up with these kind of issues

I feel finally to do the readback of these timing regsiters, would finally confirm that whether my .timing0 = 0x0010000c, .timing1 = 0x00230010, would configure..400khz, could you please help how to readback these registers can be done..through I2C in the above patch..

Because I suspect the below code is missing sorry if am wrong in the above patch, could you please me how read back of these registers can be done with any code changes.. as am week in scoping out the waveforms

static struct mxs_i2c_plat_data i2c1_platdata = {

#ifdef CONFIG_I2C_MXS_SELECT1_PIOQUEUE_MODE

  .pioqueue_mode = 1,

#endif

#ifdef  CONFIG_I2C_MXS_SELECT1_400_MODE

        .speed =  400000,

#endif 

};

static struct mxs_i2c_plat_data i2c0_platdata = {

#ifdef CONFIG_I2C_MXS_SELECT0_PIOQUEUE_MODE

  .pioqueue_mode = 1,

#endif

#ifdef  CONFIG_I2C_MXS_SELECT0_400_MODE

        .speed =  400000,

#endif 

};

Sorry if this seems to be silly question

0 Kudos
8,105 Views
Matt_
Contributor II

Hi,

I'm sorry I can't help further as it's been a long time since I worked on this project and the code may have changed.

I had to modify linux-2.6.35.3\drivers\i2c\busses\i2c-mxs.c at the time to set up the registers directly for 400kHz operation and also noticed that it had to be fixed to re-assert these values after each I2C reset.

However there may be different code and patches now.

I think it is vital to check out the changes with a 'scope as it's easy to convince yourself that the code is right when a waveform on a scope really tells the truth.

Good Luck,

Matt.

0 Kudos
8,105 Views
srinivasanshanm
Contributor III

Hi Matt,

Once again Many Thanks a lot for your replies,

As am still using linux-2.6.35.3 for verifying 400Khz in I.MX28 EVK

Could you please..share me the code changes that you made in  linux-2.6.35.3\drivers\i2c\busses\i2c-mxs.c at that time to set up the registers directly for 400kHz operation and also ensured that it had to be fixed to re-assert these values after each I2C reset

And will try to scope it again with your code changes, hope this might resolve all problems.. w.r.t 400khz operation, as early as possible

Many Thanks in advance

0 Kudos
8,105 Views
Matt_
Contributor II

Here's our i2c-mxs.c

Please note that CONFIG_MACH_MX28PCS is set for our compilation to enable 400kHz operation - you may wish to rename this for your platform or just set it at the top of the file.

Hope this helps,

Matt

0 Kudos
8,105 Views
Matt_
Contributor II

Hi Jacky,

Yes that's fine.  Hopefully this discussion will help others.

Best regards,

Matt.

0 Kudos
8,104 Views
srinivasanshanm
Contributor III

Hi,

I wanted to configure the I2C_SCL for 400Khz, & using L2.6.35_10.12.01_ER_source so I applied the patch from the below link, & I scoped out & got the SCL freq as 436.3902 KHz on i.Mx28 EVK PCB  REV D, but I need to configure to 400Khz, but I didn't understand why this .timing2 = 0x00300030 is configured & moreover .timing0 = 0x000f0007, timing1 = 0x001f000f, is giving me a 436 Khz as shown below , could any body please let me know how this can be accurated to 400khz as soon as possible

static const struct mxs_i2c_speed_config mxs_i2c_400kHz_config = {

.timing0 = 0x000f0007,

.timing1 = 0x001f000f,

.timing2 = 0x00300030,

};

Conflict on 2 I2C buses

Many Many Thanks in advance again

0 Kudos
8,105 Views
Matt_
Contributor II

Hi,

I think you just repeated the observation I made above, i.e. the values given for 400kHz operation are not applicable to all designs.

I believe this is due to the fact that the I2C bus is not actively driven high and that the high part of the clock pulse is timed after the resistor has pulled it up above a certain level.  A high value resistor (and a lot of loads) on the early EVKs led to a slow rise time which meant that the configuration parameters you used gave around 400kHz.  I used the same configuration values on an I2C bus with one load and a low value pull up and got 436KHz as you did.

I found that the low part of the clock pulse is accurately given by the LOW_COUNT field in timing1 as (LOW_COUNT+1)/24 usec.

The high part of the clock pulse is ((HIGH-COUNT+n)/24) + rise time) usec.  I have no idea what n is and rise time depends on the pull up resistor used and the amount of loading on the I2C bus.

I found using

.timing0 = 0x0010000c,

.timing1 = 0x00230010,

gave a nice 400kHz clock for me.  Give it a go.

The reason that the high level timing has to start after the clock is sampled high is that it is quite legitimate for a slave on the I2C bus to hold the clock line low to slow down the access or temporarily stall it if the slave is busy.  The master can only count clock high when it has been released.  A slow rise time just delays when it can start counting.

Best Regards,

Matt.

0 Kudos
8,105 Views
JackyAtFreescal
Senior Contributor II

Thanks for your findings!

I verified below settings on imx28 EVK Rev. D board and here is my result:

HW_I2C_TIMING0  HW_I2C_TIMING1   tH     tL     freq.

(0x80058010)    (0x80058020)

========================================================

0x00780030      0x00800030       5.3us  5.5us  92.59kHz

0x000f0007      0x001f000f       1.08us 1.32us 416.7kHz

0x0010000c      0x00230010       1.12us 1.5us  381.7kHz

0 Kudos
8,105 Views
Matt_
Contributor II

Hi Jacky,

Thank you for looking into this.

We agree on the affect of TIMING1 and tL.

I wonder whether the discrepency on tH is due to a delay in rise time.  The EVK pulls up the signals with 4k7 and is loaded by several chips whereas I use 2k2 and one load.  The I2C interface won't start counting clock high until it sees that no-one is driving it low.

Would it be too much trouble to repeat the tests with stronger pull-ups R14 & R15?

Matt.

0 Kudos
8,105 Views
JackyAtFreescal
Senior Contributor II

CIMG2851.JPG

Without HW modification on EVK, I got this waveform on R115 (SCL) for below register settings.

HW_I2C_TIMING0  HW_I2C_TIMING1   tH     tL     freq.

(0x80058010)    (0x80058020)

========================================================

0x000d0006      0x00230010       1us    1.5us  400kHz

0 Kudos
8,105 Views
Matt_
Contributor II

Hi Jacky,

I think the slow rise time is the cause of the descrepency as plugging your values into my board gives 421kHz.

F421kHz.bmp

The original values I suggested work for me at 400kHz, so I guess the clock rate is very board dependent.

F400kHz.bmp

Matt.

0 Kudos
8,106 Views
JackyAtFreescal
Senior Contributor II

Hi Matt,

If no more issue, we will close this thread.

Regards,

Jacky

0 Kudos
8,105 Views
jimmychan
NXP TechSupport
NXP TechSupport

Which board and BSP are you using?

If you are not using the latest BSP and patches, please download them from here:

http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX28_SW&fr=gtl

0 Kudos
8,105 Views
Matt_
Contributor II

Hi Jimmy,

I'm using my own board with many details drawn from the EVK and reference schematics.

I'm using the linux 2.6.35.3 BSP with all the latest patches applied.

This is not really relevent though as:

1) I was poking the registers directly from u-boot to determine what was needed to get a 400kHz clock

2) linux-2.6.35.3\drivers\i2c\busses\i2c-mxs.c has to be modified to support any operation other than the default clock rate.

I have modified i2c-mxs.c to use the values determined above which are applied whenever the module is reset and am very happy with the scope traces showing everything working nicely at 400kHz.

I just thought this may help others if they see the same issue and give Freescale an opportunity to make a constructive comment or even to modify the code if they see fit.

Best Regards,

Matt.

0 Kudos