[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