MCF5270 I2C Master receive multiple bytes timing

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

MCF5270 I2C Master receive multiple bytes timing

1,041 Views
carlk3
Contributor I

Hi-

I've asked this NetBurner Community Forum, but haven't seen any responses.

In I2C Master RX mode, after End of ADDR Cycle, after Dummy Read from I2DR, responding to IIF, not Last Byte to be Read, after slave has released clock stretch (SCL tristated), what is it that starts the clock going again so that the slave can transmit another byte? Is it the slave releasing SCL? Read from I2DR? The clearing of IIF? 

The reason I'm asking is that I'm wondering about the lifetime of valid data in I2DR. When does it start getting overwritten with new bits?

The block diagram* in MCF5271 Reference Manual shows an In/Out Data Shift Register. Should the received data get staged there until a Read from I2DR empties I2DR? What conditions might lead to an overflow?

    -Carl

* Figure 25-1. I2C Module Block Diagram, Document Number: MCF5271RM Rev. 2 07/2006

Tags (1)
0 Kudos
6 Replies

872 Views
carlk3
Contributor I

The problem turned out to be in the code running on the PIC18 slave. The MCF5270 master was fine all along. Thanks for your help. This was a learning experience.

    -Carl

0 Kudos

872 Views
TomE
Specialist II

I'm trying to reply to this in order to try and help.

It keeps objecting to words in my post, like trying to say "there may be App Notes and Sample Code datNNN from those times that may help.", but the "datNNN" word ("NNN" is "ing") is a no-no.

Trying again for about the sixth time to get past this and other errors...

===========

These controllers are "highly conserved". The same design gets used in lots of different CPUs. So you can look for source code that handles these modules all over the place.

A quick check of the Linux sources shows a Freescale/NXP I2C Driver with exactly the same number and named control registers for the i.MX series of chips as was used in your one:

https://elixir.bootlin.com/linux/latest/source/drivers/i2c/busses/i2c-imx.c


Reading the above should answer your questions, or at least give you a working example.


There should be old sample I2C driver source code all over the place, datNNN back over 20 years. This I2C module may have been used way back in the 68HC11 or 683xx days - there may be App Notes and Sample Code datNNN from those times that may help.


If you type "if2dr i2c freescale" into Google you'll get lots of matches, including this post in this forum from 2014 with someone who didn't know the difference between "!" and "~" in "C". But there's sample code provided.


https://community.nxp.com/thread/335808


Tom

0 Kudos

872 Views
carlk3
Contributor I

Thanks, Tom. That code looks reasonably similar to what I'm already doing. I'm trying to find an intermittent bug. I notice that if I set debugger breakpoints at certain points it upsets the timing enough that I get something that looks like the bug: bad data but no errors detected. As I understand it, I2C should work down to a frequency of about DC, but then I see that SMBus, which I'm not using, does put some timeouts on things like clock stretch. So, I'm wondering if the data in I2DR goes stale after a while, or gets overwritten before I'm reading it, or who knows what.

         -Carl

0 Kudos

872 Views
carlk3
Contributor I

Digging around some more in the forums, I found a file called AN4342.rar, containing Using I2C_Sample_Code. Looking at static void i2csmbus_handler(uint8 channel) in i2c.c, I see some interesting code. Sprinkled liberally throughout are calls like _i2c_delay_1bit();* with comments like /* set TXAK to proper value: delay about 1-2bit scl cycle waiting data register updated. */ /* delay 1 scl */. I don't see anything about that in the specs (e.g., MCF5271 Reference Manual). What are those delays for?

        -Carl

* Implementation:

void _i2c_delay_1bit(void)
{
        uint16 i = _i2c_delay_loop;
        uint16 cnt;
        
        if(i)
        {
                cnt = 0xffff;
        }
        for(;i>0;i--)
        {
                *(volatile uint16*)(&MTIM_MODH) = cnt;
                MTIM_SC &= ~MTIM_SC_TSTP_MASK;
                
                while(!MTIM_SC);
                MTIM_SC = 0 | MTIM_SC_TRST_MASK | MTIM_SC_TSTP_MASK;
        }
        
        if(_i2c_delay_cnt)
        {
                *(volatile uint16*)(&MTIM_MODH) = _i2c_delay_cnt;
                MTIM_SC &= ~MTIM_SC_TSTP_MASK;
                
                while(!MTIM_SC);
                MTIM_SC = 0 | MTIM_SC_TRST_MASK | MTIM_SC_TSTP_MASK;           
        }
}
0 Kudos

872 Views
TomE
Specialist II

Type "UM10204" into Google, download and read this cover to cover if you haven't already:

https://www.nxp.com/docs/en/user-guide/UM10204.pdf 

That explains the SMBUS timeout and the minimum frequency requirements (of that variant).

You can get noise causing errors on I2C that can cause lockups. The only way out of this is to have software timeouts. That's what some of those timeouts are for.

It also explains the need for special Resets in I2C. If the CPU is reset part way through an I2C transaction, the bus is now solidly locked. You either need reset pins on all I2C peripherals (almost none have these), or you need to force at least 9 clocks on the bus to clear it on power-on. Pretty much no I2C controller supports this feature, so you have to have separate hardware to do this, or an I2C interface you can program as a GPIO and bit-bang that sequence. This is an original "design bug" in I2C that has taken over 30 years to get fixed in the drivers in Linux. And in many distributions it hasn't been fixed yet.

You can find details on this and more in this post here that I responded to (2013 to 2017):

I2C reset 

Also an earlier (2012) one:

Problems with I2C on MCF5208 

> _i2c_delay_1bit()

Interesting. No idea. Is there anything like that in the Linux sources? Yes, there is:

/*
 * There dummy delay is calculated.
 * It should be about one I2C clock period long.
 * This delay is used in I2C bus disable function
 * to fix chip hardware bug.
 */
 i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
        + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);

...
 /*
  * This delay caused by an i.MXL hardware bug.
  * If no (or too short) delay, no "STOP" bit will be generated.
  */
  udelay(i2c_imx->disable_delay);

It is possible the I2C controller is so old it was being used in the days of 1 MHz 6800's and also in slow 68HC11's, and those CPUs weren't fast enough to show these problems. Nobody would have expected the same hardware to be driven by a 1.2GHz i.MX CPU, or a 150MHz MCF52xx chip.

> I don't see anything about that in the specs

There are quite a few examples of things like that posted in these forums. You should search to see if anyone else has asked that question, and post back here if you find anything.

> Digging around some more in the forums, I found a file called AN4342

Could you add links to any interesting posts you found to this post? Searching for "AN4342" I found 18.

Tom

0 Kudos

872 Views
TomE
Specialist II

These controllers are "highly conserved". The same design gets used in lots of different CPUs. So you can look for source code that handles these modules all over the place.

A quick check of the Linux sources shows a Freescale/NXP I2C Driver with exactly the same number and named control registers for the i.MX series of chips as was used in your one:

Linux source code: drivers/i2c/busses/i2c-imx.c (v5.0.4) - Bootlin 

--- I keep getting "Your upload contains banned content", so I'm going to have to post a few lines at a time until I can work out what this system is objecting to, this makes it REALLY hard to try and help!

Reading the above should answer your questions, or at least give you a working example.

There should be old sample I2C driver source code all over the place,

Tom

0 Kudos