public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Heiko Schocher <hs@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 19/31] i2c, mpc83xx: add CONFIG_SYS_I2C_INIT_BOARD for fsl_i2c
Date: Wed, 28 Jan 2009 13:04:41 +0100	[thread overview]
Message-ID: <498049D9.9030605@denx.de> (raw)
In-Reply-To: <OF928E968D.DB6002D5-ONC125754C.003E609A-C125754C.003F1A81@transmode.se>

Hello Joakim,

Joakim Tjernlund wrote:
> Heiko Schocher <hs@denx.de> wrote on 28/01/2009 11:54:22:
>> Joakim Tjernlund wrote:
>>>> This patch adds the possibility to call a board specific
>>>> i2c bus reset routine for the fsl_i2c bus driver, and adds
>>>> this option for the keymile kmeter1 board.
>>>>
>> [...]
>>>> @@ -478,6 +480,17 @@ static int i2c_make_abort (void)
>>>>   */
>>>>  void i2c_init_board(void)
>>>>  {
>>>> +#if defined(CONFIG_KMETER1)
>>>> +   struct fsl_i2c *dev;
>>>> +   dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + 
> CONFIG_SYS_I2C_OFFSET);
>>>> +   uchar   dummy;
>>>> +
>>>> +   out_8 (&dev->cr, (I2C_CR_MSTA));
>>>> +   out_8 (&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
>>>> +   dummy = in_8(&dev->dr);
>>>> +   out_8 (&dev->cr, (I2C_CR_MEN));
>>> Are you sure this will generate a proper I2C reset sequence? We also
>>> use this controller and I tried to do it too but didn't find a way. I 
> then 
>>> asked
>>> Freescale and they could not come up with a solution either.
>> ?
>> This routine is decribed in the MPC8260ERM.pdf ?15.5.7 on page 15-23
>> from Freescale!
>>
>> 15.5.7 Generation of SCLn when SDAn is Negated
>> It is sometimes necessary to force the I2C module to become the I2C bus 
> master out of reset and drive
>> SCLn (even though SDAn may already be driven, which indicates that the 
> bus is busy). This can occur
>> when a system reset does not cause all I2C devices to be reset. Thus, 
> SDAn can be negated low by another
>> I2C device while this I2C module is coming out of reset and will stay 
> low indefinitely. The following
>> procedure can be used to force this I2C module to generate SCLn so that 
> the device driving SDAn can
>> finish its transaction:
>> 1. Disable the I2C module and set the master bit by setting I2CnCR to 
> 0x20.
>> 2. Enable the I2C module by setting I2CnCR to 0xA0.
>> 3. Read I2CnDR.
>> 4. Return the I2C module to slave mode by setting I2CnCR to 0x80.
>>
>> And this worked fine on our Hardware ...
> 
> Ahh, memory slowly returns. The problem is that this does not generate a 
> reset
> sequence that will work in all cases. Consider the case when the
> CPU is reset half-way through writing or reading a byte from the device.
> 
> I once researched this(can't remember the exact details now) but the
> only reset sequence that works in all cases is:
> 
> static void send_start(void)
> {
>         I2C_DELAY;
>         I2C_TRISTATE;
>         I2C_SDA(1);
>         I2C_DELAY;
>         I2C_SCL(1);
>         I2C_DELAY;
>         I2C_SDA(0);
>         I2C_ACTIVE;
>         I2C_DELAY;
> }
> 
> static void send_stop(void)
> {
>         I2C_SCL(0);
>         I2C_DELAY;
>         I2C_SDA(0);
>         I2C_ACTIVE;
>         I2C_DELAY;
>         I2C_SCL(1);
>         I2C_DELAY;
>         I2C_TRISTATE;
>         I2C_SDA(1);
>         I2C_DELAY;
> }
> 
> /*-----------------------------------------------------------------------
>  * Send a reset sequence consisting of 9 clocks with the data signal high
>  * to clock any confused device back into an idle state.  Also send a
>  * <stop> at the end of the sequence for belts & suspenders.
>  */
> void tm_i2c_reset(int bus)
> {
>         int j;
> 
>         I2C_INIT;
>         I2C_TRISTATE;
>         for(j = 0; j < 9; j++) {
>                 if(I2C_READ)
>                         send_start();
>                 I2C_SCL(0);
>                 I2C_DELAY;
>                 I2C_TRISTATE;
>                 I2C_SDA(1);
>                 I2C_DELAY;
>                 I2C_SCL(1);
>                 I2C_DELAY;
>                 I2C_DELAY;
>         }
>         send_stop();
>         if(!I2C_READ)
>                 printf("I2C SDA is low! I2C bus:%d is stuck!!!\n", bus);
> }

I dont know if it is possible to make this with the 8360 ...

Maybe we can do the following:
- make the reset Sequence suggested from Freescale
- checking the Status Register, if the Bus is now free (MBB Bit = 0)
  If not, do again the reset Sequence. And this for max. 9 times.

What do you think?

bye
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

  reply	other threads:[~2009-01-28 12:04 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-28  9:40 [U-Boot] [PATCH 19/31] i2c, mpc83xx: add CONFIG_SYS_I2C_INIT_BOARD for fsl_i2c Heiko Schocher
2009-01-28 10:15 ` Joakim Tjernlund
2009-01-28 10:54   ` Heiko Schocher
2009-01-28 11:28     ` Joakim Tjernlund
2009-01-28 12:04       ` Heiko Schocher [this message]
2009-01-28 13:14         ` Joakim Tjernlund

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=498049D9.9030605@denx.de \
    --to=hs@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox