Dears, we have an am335x based board with ti-sdk-am335x-evm-06.00.00.00 u-boot, adaped for our hardware. We configured i2c-2 in u-boot as follow:
----------------------------------------------------file: pinmux.h
MUX_VAL(CONTROL_PADCONF_UART1_CTSN, (IDIS | PU | MODE3 ))//df db (IEN | OFF | MODE3 ))
MUX_VAL(CONTROL_PADCONF_UART1_RTSN, (IDIS | PU | MODE3 ))//df db (IEN | OFF | MODE3 ))
----------------------------------------------------file: mux.h
static struct module_pin_mux i2c2_pin_mux[] = {
{OFFSET(uart1_ctsn), (MODE(3) | RXACTIVE)}, /* I2C_DATA */
{OFFSET(uart1_rtsn), (MODE(3) | RXACTIVE)}, /* I2C_SCLK */
{-1},
};
void enable_i2c2_pin_mux(void)
{
configure_module_pin_mux(i2c2_pin_mux);
}
----------------------------------------------------file: board.c
...
#ifdef CONFIG_NOR_BOOT
am33xx_spl_board_init();
#endif
enable_i2c2_pin_mux();
//---------------------- commented i2c_init(CONFIG_SYS_I2C_SPEED, 2);
...
----------------------------------------------------file: i2c.h
...
#define I2C_BASE1 0x44E0B000
#define I2C_BASE2 0x4802A000
#define I2C_BASE3 0x4819C000
#define I2C_BUS_MAX 3
...
----------------------------------------------------
----------------------------------------------------file: omap24xx_i2c.c
---------------------------------------------------- the u-boot hang at i2c_init line: if (readw(&i2c_base->con) & I2C_CON_EN)
when in u-boot shell I execute: i2c dev 2
any other thing I need to do? seems that: access memory>=I2C_BASE3 bugs the chip am335x. Need configure any other register or do any other process before initialize i2c-2?
NOTE: We use internal clock.
void i2c_init(int speed, int slaveadd)
{
int psc, fsscll, fssclh;
int hsscll = 0, hssclh = 0;
u32 scll, sclh;
int timeout = I2C_TIMEOUT;
/* Only handle standard, fast and high speeds */
if ((speed != OMAP_I2C_STANDARD) &&
(speed != OMAP_I2C_FAST_MODE) &&
(speed != OMAP_I2C_HIGH_SPEED)) {
printf("Error : I2C unsupported speed %d\n", speed);
return;
}
psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
psc -= 1;
if (psc < I2C_PSC_MIN) {
printf("Error : I2C unsupported prescalar %d\n", psc);
return;
}
if (speed == OMAP_I2C_HIGH_SPEED) {
/* High speed */
/* For first phase of HS mode */
fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK /
(2 * OMAP_I2C_FAST_MODE);
fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM;
fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM;
if (((fsscll < 0) || (fssclh < 0)) ||
((fsscll > 255) || (fssclh > 255))) {
puts("Error : I2C initializing first phase clock\n");
return;
}
/* For second phase of HS mode */
hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM;
hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM;
if (((fsscll < 0) || (fssclh < 0)) ||
((fsscll > 255) || (fssclh > 255))) {
puts("Error : I2C initializing second phase clock\n");
return;
}
scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll;
sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh;
} else {
/* Standard and fast speed */
fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
fsscll -= I2C_FASTSPEED_SCLL_TRIM;
fssclh -= I2C_FASTSPEED_SCLH_TRIM;
if (((fsscll < 0) || (fssclh < 0)) ||
((fsscll > 255) || (fssclh > 255))) {
puts("Error : I2C initializing clock\n");
return;
}
scll = (unsigned int)fsscll;
sclh = (unsigned int)fssclh;
}
************************************************************ u-boot hang EXECUTING readw(&i2c_base->con)
if (readw(&i2c_base->con) & I2C_CON_EN) {
************************************************************
writew(0, &i2c_base->con);
udelay(50000);
}
writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
udelay(1000);
writew(I2C_CON_EN, &i2c_base->con);
while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
if (timeout <= 0) {
puts("ERROR: Timeout in soft-reset\n");
return;
}
udelay(1000);
}
writew(0, &i2c_base->con);
writew(psc, &i2c_base->psc);
writew(scll, &i2c_base->scll);
writew(sclh, &i2c_base->sclh);
/* own address */
writew(slaveadd, &i2c_base->oa);
writew(I2C_CON_EN, &i2c_base->con);
/* have to enable intrrupts or OMAP i2c module doesn't work */
writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
udelay(1000);
flush_fifo();
writew(0xFFFF, &i2c_base->stat);
writew(0, &i2c_base->cnt);
if (gd->flags & GD_FLG_RELOC)
bus_initialized[current_bus] = 1
}