[U-Boot-Users] I2C Initialization
Joakim Tjernlund
joakim.tjernlund at lumentis.se
Wed Mar 12 09:31:46 CET 2003
> For I2C Reset it is adviseable to cause at least a sequence of eight STOP
> one START and another STOP condition. Some Manufacturers (Microchip when I
> remember correctly) require that because in violation of the I2C Spec they
> do not recognize a STOP condition while expecting the Bits of a Byte.
> Otherwise you might end up writing an arbitrary value the last addressed
> location in your I2C memory if the previous transfer has been interrupted in
> an unfortunate state... (see also I2C Edge Conditions, which addresses a
> part of the Problem).
Hi
I have a DS1337 RTC which hangs if you press the reset button while doing
hwclock. To "unhang" the DS1337 I have to remove the battery :-(.
I figured the above I2C reset trick would help, but so far nothing helps.
I copied parts of mpc8xx/soft_i2c.c in my ppcboot(1.0.5) and hacked
a I2C Reset function that is called from misc_init_r().
Someone else that has this problem or can see what I am doing wrong?
This is my i2c reset hack:
#define PB_SCL 0x00000020 /* PB 26 */
#define PB_SDA 0x00000010 /* PB 27 */
#define SET_PB_BIT(bit) do { \
immr->im_cpm.cp_pbdir |= bit; /* output */ \
immr->im_cpm.cp_pbdat |= bit; /* set 1 */ \
udelay (5); \
} while (0)
#define RESET_PB_BIT(bit) do { \
immr->im_cpm.cp_pbdir |= bit; /* output */ \
immr->im_cpm.cp_pbdat &= ~bit; /* set 0 */ \
udelay (5); \
} while (0)
/*-----------------------------------------------------------------------
* START: High -> Low on SDA while SCL is High
*/
static void send_start (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
SET_PB_BIT (PB_SCL);
udelay (10);
RESET_PB_BIT (PB_SDA);
udelay (20);
}
/*-----------------------------------------------------------------------
* STOP: Low -> High on SDA while SCL is High
*/
static void send_stop (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
RESET_PB_BIT (PB_SDA);
udelay (10);
SET_PB_BIT (PB_SCL);
udelay (10);
SET_PB_BIT (PB_SDA);
udelay (20);
}
void my_i2c_reset(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_cpm.cp_pbpar &= ~(PB_SCL | PB_SDA); /* GPIO */
immr->im_cpm.cp_pbodr |= (PB_SCL | PB_SDA); /* Open Drain Output */
send_stop();
send_stop();
send_stop();
send_stop();
send_stop();
send_stop();
send_stop();
send_stop();
send_start();
send_stop();
}
More information about the U-Boot
mailing list