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.

i2c1 at u-boot level

Other Parts Discussed in Thread: TCA6416

Hi,

i want to use i2c1 at u-boot level. i'm using u-boot code from AM335x EVM, in u-boot code "board/ti/am335x/evm.c" i saw the include file <i2c.h>, and how it use to enable i2c0,

can i really use <i2c.h> header file to enable i2c1 as well? any changes needed?

Thanks

Keldy

  • Hi Keldy,

    In u-boot i2c0 is enabled by default, you can go through "read_eeprom()" API for usage.

    can i really use <i2c.h> header file to enable i2c1 as well? any changes needed?

    Yes, you have to add i2c.h

    i2c1 sould be register in the simillar lines as that of i2c0.

    * Do proper pinmuxing

    * enable i2c1 clocks

    * i2c_int()

    Note: In software I2C instances are starting from 1 instead of 0 (HW)

    Regards

    AnilKumar

    Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question.  Thanks!

  • Also you need to setup pin-mux for i2c1 pins.

    so you need to setup

    1. i2c1 clocks

    2. i2c1 pin-mux

    3. proper i2c1 base address to be used by omap-i2c driver

    4. verify that the omap-i2c driver supports multi-bus and use it accordingly

    Regards

    Gururaja

  • Hi All,

    I build a i2c1 function inside u-boot code, ("board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c"), in this case, i plan to communicate with i2c port expander (tca6416) with chip address 0x20, communication speed 400k.

    ___________________________________________________________________

    void i2c1(void)
    {
     u32 val;
     val = __raw_readl(CONF_SPI0_D1);            //pin_mux i2c1_sda
     val = (val & 0xFFFFFFF1 | 0x2);
     __raw_writel(val, CONF_SPI0_D1);

     val = __raw_readl(CONF_SPI0_CS0);            //pin_mux i2c1_scl
     val = (val & 0xFFFFFFF1 | 0x2);
     __raw_writel(val, CONF_SPI0_CS0);

     i2c_init(400000, 0x20); //i2c speed 400k, i2c port expander (tca6416) chip address 0x20
     
     printf("sending value = 0xFF\n");           //write value
     i2c_write(0x20, 0x06, 1, 0xFF, 1);
     
     uchar read_val;        //read value
     printf("reading value :");
     i2c_read(0x20, 0x06, 1, &read_val, 1);
     printf("%d\n", read_val); 
    }

    ___________________________________________________________________

    am i correct? is the i2c_init(), i2c_write(), i2c_read() functions applicable for i2c1 ?

    Thanks & Regards

    Keldy  

  • I dont think thats enough. By default u-boot i2c driver will be working for i2c-0 instance. so you need to switch it to i2c-1 instance.

    Also look at board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/mux.c on how i2c0 pin-mux is done. 

    Have you set i2c1 clocks (controller clocks & not i2c device clocks). for this look at board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/pll.c

  • Hi,

    in "board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/mux.c"

    i have changed: PULLUDEN to PULLUDDIS (because i use external pull-up)

    static struct module_pin_mux i2c1_pin_mux[] = {
     {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | PULLUDDIS | SLEWCTRL)}, /* I2C_DATA */
     {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | PULLUDDIS | SLEWCTRL)}, /* I2C_SCLK */
     {-1},
    };

    and i have add new function:

    void enable_i2c1_pin_mux(void)
    {
     configure_module_pin_mux(i2c1_pin_mux);
    }

    in "board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c"

    void i2c1(void)
    {

    enable_i2c1_pin_mux(); //set pin mux
     
     /* enable clock i2c1 */
     __raw_writel(0x2, CM_PER_I2C1_CLKCTRL);
     while (__raw_readl(CM_PER_I2C1_CLKCTRL) != 0x2);
     
     i2c_init(400000, 0x20); //i2c speed 400k, chip address 0x20
     
     printf("sending value = 0xFF\n");           //write value
     i2c_write(0x20, 0x06, 1, 0xFF, 1);
     
     uchar read_val;        //read value
     printf("reading value :");
     i2c_read(0x20, 0x06, 1, &read_val, 1);
     printf("%d\n", read_val); 
     
    }

    how i switch u-boot i2c driver to i2c-1 instance?

    Thanks & Regards

    Keldy

  • Hi Keldy,

    Replace this line
     i2c_init(400000, 0x20); //i2c speed 400k, chip address 0x20

    with
     i2c_init(400000, 2); //i2c speed 400k, chip id 2 /* instance 1 */

    Regards

    AnilKumar

    Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question.  Thanks!

  • Hi,

    my u-boot hang while execute the i2c1() function, the i2c_write() cause the u-boot hang.

    void i2c1 (void)

    {

     enable_i2c1_pin_mux();
     
     /* enable clock i2c1 */
     __raw_writel(0x2, CM_PER_I2C1_CLKCTRL);
     while (__raw_readl(CM_PER_I2C1_CLKCTRL) != 0x2);
     
     i2c_init(400000, 2); //i2c speed 400k, chip address 0x20
     
     printf("sending value = 0xFF\n");           //write value
     i2c_write(0x20, 0x06, 1, 0xFF, 1);         //-----------------------------------------------------------------------------this line cause the u-boot hang
     uchar read_val;        //read value
     printf("reading value :");
     i2c_read(0x20, 0x06, 1, &read_val, 1);
     printf("%d\n", read_val); 
    }

    Any wrong with my code, what i have miss to configure?

    Thanks & Regards

    Keldy

  • Hi Keldy,

    Looking at the board/ti/am335x/evm.c , only  pinmuxing and i2c_init is done did you add both these in
    board_init() function itself? are you sure the i2c speed for i2c1 is 400000?

    Thx,

    --Prabhakar Lad

  • Hi Keldy,

    Remove "enable clock i2c1" code from your9 part. Because all the I2C clocks are enabled in u-boot in "pll_init()"

    You have to call your API (i2c1) after pll_init() call.

    Regards

    AnilKumar

    Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question.  Thanks!

  • Hi,

    in "/board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c

    under function: s_init(void) :

    void s_init(void)
    {
     /* Can be removed as A8 comes up with L2 enabled */
     l2_cache_enable();

     /* WDT1 is already running when the bootloader gets control
      * Disable it to avoid "random" resets
      */
     __raw_writel(0xAAAA, WDT_WSPR);
     while(__raw_readl(WDT_WWPS) != 0x0);
     __raw_writel(0x5555, WDT_WSPR);
     while(__raw_readl(WDT_WWPS) != 0x0);

    #ifdef CONFIG_SPL_BUILD
     /* Setup the PLLs and the clocks for the peripherals */
     pll_init();
     i2c1();  ---------------------------------------------------------------- my API i2c1();

    The u-boot no hang anymore, but seen like the u-boot didn't execute i2c1(), because it didn't printf the message inside the i2c1(void) function.

    do i need to call the function s_init() inside board_init() function ?

    Thanks & Regard

    Keldy

  • Hi Keldy,

    Can you add next to config_am335x_ddr();? I think console is not initialized at your step.

    Regards

    AnilKumar

    Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question.  Thanks!

  • Hi,

    void s_init(void)
    {
     /* Can be removed as A8 comes up with L2 enabled */
     l2_cache_enable();

     /* WDT1 is already running when the bootloader gets control
      * Disable it to avoid "random" resets
      */
     __raw_writel(0xAAAA, WDT_WSPR);
     while(__raw_readl(WDT_WWPS) != 0x0);
     __raw_writel(0x5555, WDT_WSPR);
     while(__raw_readl(WDT_WWPS) != 0x0);

    #ifdef CONFIG_SPL_BUILD
     /* Setup the PLLs and the clocks for the peripherals */
     pll_init();
     
     /* UART softreset */
     u32 regVal;
     u32 uart_base = DEFAULT_UART_BASE;

     enable_uart0_pin_mux();
     /* IA Motor Control Board has default console on UART3*/
     /* XXX: This is before we've probed / set board_id */
     if (board_id == IA_BOARD) {
      uart_base = UART3_BASE;
     }

     regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET);
     regVal |= UART_RESET;
     __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) );
     while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) &
       UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);

     /* Disable smart idle */
     regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
     regVal |= UART_SMART_IDLE_EN;
     __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));

     /* Initialize the Timer */
     init_timer();

     preloader_console_init();

     config_am335x_ddr();
     i2c1(); ----------------------------------------------------------------------------my i2c1 API
    #endif
    }

    the result still the same, the u-boot didn't execute the i2c1().

    Thanks & Regards

    Keldy

  • HI All;

    if your paritcular i2c need to be worked means,

    which bus you are using, need to initialize in i2c_init function last line okay!

    bus_initialized[current_bus] = X; // X is the bus number

    It' will work!!!!!!!!!!

    Regards

    santosh vastrad

  • Is there any guide to do this with the latest sdk 7.0 as the u-bot does not have the files in the same location or the same files as this post suggests.  Thanks

  • Someone has success with i2c-1 or i2c-2 communication? 

    I followed all steps described here, it still does not work. bellow is the pinmux struct used:

    static struct module_pin_mux i2c2_pin_mux[] = {
        {OFFSET(uart1_ctsn), (MODE(3) | RXACTIVE |
        PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
        {OFFSET(uart1_rtsn), (MODE(3) | RXACTIVE |
        PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
        {-1},
    };

    another thing, chip revision:

    AM3359ZCZD72

    34AOGNW

                                    ZCZ

  • Hi Daniel. I need i2c1 also. Did you have any success with it? .......................dd