[U-Boot] [PATCH 19/31] i2c, mpc83xx: add CONFIG_SYS_I2C_INIT_BOARD for fsl_i2c

Heiko Schocher hs at denx.de
Wed Jan 28 13:04:41 CET 2009


Hello Joakim,

Joakim Tjernlund wrote:
> Heiko Schocher <hs at 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


More information about the U-Boot mailing list