This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x I2C2 access in U-boot

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

}

  • Are you enabling the functional clock for I2C2?  (See register CM_PER_I2C2_CLKCTRL at 0x44e00044, should be 0x2).  I would use the I2C1 example in uboot to determine the proper way to do this in uboot.   

    Regards,

    James

  • yes James, enable clock was missing, but unfortunately it still hang at line: 

    if (readw(&i2c_base->con) & I2C_CON_EN) {

    in the file: omap24xx_i2c.c
    function:   void i2c_init(int speed, int slaveadd)

    It seems that readw fail to access the address of i2c-2: 

    if (bus == 2) {
       i2c_base = (struct i2c *)I2C_BASE3;

    Where I2C_BASE3 == 0x4819c000.  For i2c-0 and i2c-1 all works well, but to access 0x4819c000 memory base does' t work. Is there something else to enable access for this memory range? Some compilation parameter?

     

    thanks.

     

  • Hi, 

    I don't get where you tell to use I2C2 bus in the uboot .... In the I2C_init function you have this line :

    I2C_ADAP->init(I2C_ADAP, speed, slaveaddr);

    and it use the older bus number ! not the new one.

    I don't understand !