I2C communication

Hi All

 

I am actually new to Renesas Synergy Platform, So pls bear with my simple doubts

 

Currently i am working on establishing an I2C communication between S7G2 synergy micro controller and IO Expander IC (max7312).

Here My controller is Master and IO Expander IC is Slave.

The purpose of IO Expander IC is to take 16 Digital Inputs and giving the status to microcontroller through I2C bus

 

So my question here is that is I2C Master Driver sufficient to establish the communication or I2C Slave Driver are also required to carry on the communication between both

 

 

Thanks in advance

Dushyant

  • Hi,

    You only need the master driver.

    Regards,

    Ian.
  • In reply to Ian:

    Thanks Ian for the help.

    I will be requiring more of it once i write the code

    Regards
    Dushyant
  • In reply to Dushy:

    Hello All


    Below is my simple code i have written for I2C communication for reading Digital Inputs status.

    But i am not able to get the desired result. I am really stuck on it

    Request you all for your expert advice on where i am going wrong and help me out to get out of this problem





    #include <string.h>
    #include "hal_data.h"

    void i2c_riic_slave_hal_mg(void);


    #define BUF_LEN1 (1)
    #define BUF_LEN2 (1)
    #define BUF_LEN3 (1)



    /* Event flags for master and slave */
    volatile bool master_rx_complete = false;
    volatile bool master_tx_complete = false;
    volatile bool master_aborted = false;



    void i2c_riic_slave_hal_mg(void)
    {
    /* Define the units to be used with the software delay function */
    const bsp_delay_units_t bsp_delay_units = BSP_DELAY_UNITS_MILLISECONDS;

    /* Set the blink frequency (must be <= bsp_delay_units */
    const uint32_t freq_in_hz = 2;

    /* Calculate the delay in terms of bsp_delay_units */
    const uint32_t delay = (bsp_delay_units)/freq_in_hz;


    /* Master transmit buffer */

    uint8_t master_tx2_buf[BUF_LEN3] = {0x00}; // ( max7312 IC )COMMAND BYTE ADDRESS (HEX) - 0x00 , FUNCTION
    PROTOCOL - Input port 1




    /* Master receive buffer */

    uint8_t master_rx_buf[BUF_LEN2];

    int result;
    ssp_err_t err;


    /* Open mater I2C instance */
    err = g_i2c_master.p_api->open(g_i2c_master.p_ctrl, g_i2c_master.p_cfg);


    /* Delay */
    R_BSP_SoftwareDelay(delay, bsp_delay_units);




    while(1)
    {


    /* Start Master write */

    err = g_i2c_master.p_api->write(g_i2c_master.p_ctrl, master_tx2_buf, BUF_LEN3, false);


    /* Delay */
    R_BSP_SoftwareDelay(delay, bsp_delay_units);


    /* Start master read. Master has to initiate the transfer. */

    err = g_i2c_master.p_api->read(g_i2c_master.p_ctrl, master_rx_buf, BUF_LEN2, false);



    /* Wait until master read complete */
    while(false == master_rx_complete);

    master_rx_complete = false;


    result = master_rx_buf;


    /* Delay */
    R_BSP_SoftwareDelay(delay, bsp_delay_units);

    }
    }

    /* Master I2C callback function */

    void i2c_master_callback(i2c_callback_args_t * p_args)
    {
    if (I2C_EVENT_RX_COMPLETE == p_args->event)
    {
    master_rx_complete = true;
    }


    else if (I2C_EVENT_ABORTED == p_args->event)
    {
    master_aborted = true;
    }

    }
  • In reply to Dushy:

    Request you all to pls kindly have a look at my problem and suggest me the solution


    Thanks in advance
    Dushyant
  • In reply to Dushy:

    Hi,

    You are assigning the return of the API calls to variable "err" but never checking it. This may help determine the problem.

    In your callback you only have code for the RX event. Can you add code for the TX event and wait for the flag after the write?

    Regards,

    Ian.
  • In reply to Ian:

    Hi

    Thanks for your help

    Now i feel my loop is running properly and is not stucking anywhere.

    But what i am getting now in p_dest pointer "master_rx_buf " is a constant value of ( 195 'Ã' ) even when i am changing the state of digital input state of all the pins

    err = g_i2c_master.p_api->read(g_i2c_master.p_ctrl, master_rx_buf, BUF_LEN2, false);

    ideally it should change when i am changing the digital inputs at the Pins.

    Can you pls guide me why it is not changing or the value i am getting is an address where the variable is stored and i need to extract it. I am confused

    Pls help





    thanks & Regards
    Dushyant
  • In reply to Dushy:

    Hi,

    Are you looking at the content of master_rx_buf or the value in result? You are assigning result which is type int to master_rx_buf which is an array of uint8_t. I would expect the compiler to be issuing a warning about this as this will not give you the desired result.

    What does the read API return in err?

    Regards,

    Ian.
  • Hello Dushyant,

    Have you finally got the I2C communication work properly?

    Kind regards
  • In reply to Sergey Sokol:

    hi Sergey

    Sorry for late reply but I am still stuck with it and pls find below my progress on it and pls help me out to resolve it

    So below is the latest code I am working on:

    ****************************************Start of Code***********************************************

    #include <string.h>
    #include "hal_data.h"

    void i2c_riic_slave_hal_mg(void);


    void i2c_riic_slave_hal_mg(void)
    {
        /* Define the units to be used with the software delay function */
        const bsp_delay_units_t bsp_delay_units = BSP_DELAY_UNITS_MILLISECONDS;
        /* Set the blink frequency (must be <= bsp_delay_units */
        const uint32_t freq_in_hz = 2;
        /* Calculate the delay in terms of bsp_delay_units */
        const uint32_t delay = (bsp_delay_units)/freq_in_hz;


        uint8_t command[16],reg[3];

        ssp_err_t err;

        uint8_t i;

        uint8_t count;


        /* Open mater I2C instance */
        err = g_i2c_master.p_api->open(g_i2c_master.p_ctrl, g_i2c_master.p_cfg);

        if (err)
                __BKPT();

     

                /* Delay */
                    R_BSP_SoftwareDelay(delay, bsp_delay_units);

     

    i = 0;
    count = 0;

       while(1)

       {

               /* Start Master write */
                        command[0] = 0x06;
                        command[1] = 0x07;
                        command[2] = 0xFF;
                        command[3] = 0xFF;
                         
     err = g_i2c_master.p_api->write(g_i2c_master.p_ctrl, &command[0], 4 , false);

                         if (err)
                                     __BKPT();

                          /* Delay */
                                          R_BSP_SoftwareDelay(delay, bsp_delay_units);

     

            /* Start master read.  Master has to initiate the transfer. */
            command[0] = 0x00;
            command[1] = 0x01;

     

            err = g_i2c_master.p_api->write(g_i2c_master.p_ctrl, &command[0], 2 , false);

                                 if (err)
                                             __BKPT();


                       /* Delay */
                         R_BSP_SoftwareDelay(delay, bsp_delay_units);

             err = g_i2c_master.p_api->read(g_i2c_master.p_ctrl, &reg[0], 1, false);

            if (err)
                        __BKPT();


            if (0==i)

            {
                count = 8;
            }

            else
            {
                count = 5;
            }

            i = (uint8_t)(1-i);


            /* Delay */
            R_BSP_SoftwareDelay(delay, bsp_delay_units);

        }

    }

    ****************************************End of Code***********************************************

    And now below are my observations on the same

    1.  err = g_i2c_master.p_api->open(g_i2c_master.p_ctrl, g_i2c_master.p_cfg);   // This API is showing Success

    2.  err = g_i2c_master.p_api->write(g_i2c_master.p_ctrl, &command[0], 4 , false); // Here my loop is halting and err variable shows "SSP_ERR_ABORTED". My loop does not go beyond that

    3. When I check the SDA & SCL lines on Oscilloscope

     

     


    This is the datasheet of my Slave Device. The Slave device address i have kept is 0x40 (AD0, AD1, AD2 - All ground)
     

     

    Request you all to pls suggest me the possible cause of problem and solution to it

    Thanks in advance

    Dushyant

     

  • In reply to Dushy:

    Also pls find the Slave device datasheet

     

     

    https://www.mouser.in/datasheet/2/256/max7312-1178306.pdf

     

    Also find all the relevant screenshots for better understanding of the problem

  • In reply to Dushy:

    Just to add one more observation

    when i am observing the I2C Bus Mode Register 1 (ICMR1) and in that Bit 7, which is MST/TRS Write Protect, the bit is reading as 0.
    if i am assuming correctly it is protecting the write API to write to these bits.

    Pls suggest if it the root cause or not related to the problem

    thanks
    dushyant
  • In reply to Dushy:

    hi
    Awaiting responses from all the experts to resolve my problem

    regards
    dushyant
  • In reply to Dushy:

    Hi

    The issue has been resolved now and is working OK.

    Thanks