I2C read write operation using RZ/V2L -M33

How to implement I2C read write functions for M33 in RZ/V2L

Below is the sensor driver header function

#ifndef _MLX90641_I2C_Driver_H_
#define _MLX90641_I2C_Driver_H_

#include <stdint.h>

void MLX90641_I2CInit(void);
int MLX90641_I2CGeneralReset(void);
int MLX90641_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data);
int MLX90641_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data);
void MLX90641_I2CFreqSet(int freq);
#endif

This what I tried.


void MLX90641_I2CSetup(){
    R_RIIC_MASTER_Open(i2c_ctrl, &cfg);
}

void MLX90641_I2CInit()
{

MLX90641_I2CSetup();
}

Not sure if this approach is correct as I have defined comms_i2c_callback_IR_sensor callback function not sure when it will be used

My hal_data.c looks like this:

/* generated HAL source file - do not edit */
#include "hal_data.h"
/* I2C Communication Device */
#define FSP_NOT_DEFINED (1)
rm_comms_i2c_instance_ctrl_t g_comms_i2c_device0_ctrl;

/* Lower level driver configuration */
const i2c_master_cfg_t g_comms_i2c_device0_lower_level_cfg =
{ .slave = 0x33, .addr_mode = I2C_MASTER_ADDR_MODE_7BIT, };

const rm_comms_cfg_t g_comms_i2c_device0_cfg =
{ .semaphore_timeout = 0xFFFFFFFF, .p_lower_level_cfg = (void*) &g_comms_i2c_device0_lower_level_cfg, .p_extend =
(void*) &g_comms_i2c_bus0_extended_cfg,
.p_callback = comms_i2c_callback_IR_sensor,
#if defined(NULL)
.p_context = NULL,
#else
.p_context = (void*) &NULL,
#endif
};

const rm_comms_instance_t g_comms_i2c_device0 =
{ .p_ctrl = &g_comms_i2c_device0_ctrl, .p_cfg = &g_comms_i2c_device0_cfg, .p_api = &g_comms_on_comms_i2c, };
iic_master_instance_ctrl_t g_i2c_master0_ctrl;
const riic_master_extended_cfg_t g_i2c_master0_extend =
{ .timeout_mode = IIC_MASTER_TIMEOUT_MODE_SHORT,
/* Actual calculated bitrate: 98425. Actual calculated duty cycle: 50%. */.clock_settings.brl_value = 28,
.clock_settings.brh_value = 28,
.clock_settings.cks_value = 4,
.noise_filter_stage = 1,
.naki_irq = RIIC0_NAKI_IRQn,
.spi_irq = RIIC0_SPI_IRQn,
.sti_irq = RIIC0_STI_IRQn,
.ali_irq = RIIC0_ALI_IRQn,
.tmoi_irq = RIIC0_TMOI_IRQn, };
const i2c_master_cfg_t g_i2c_master0_cfg =
{ .channel = 0,
.rate = I2C_MASTER_RATE_STANDARD,
.slave = 0x00,
.addr_mode = I2C_MASTER_ADDR_MODE_7BIT,
#define FSP_NOT_DEFINED (1)
#undef FSP_NOT_DEFINED
.p_callback = NULL,
.p_context = NULL,
.rxi_irq = RIIC0_RI_IRQn,
.txi_irq = RIIC0_TI_IRQn,
.tei_irq = RIIC0_TEI_IRQn,
.ipl = 12,
.p_extend = &g_i2c_master0_extend, };
/* Instance structure to use this module. */
const i2c_master_instance_t g_i2c_master0 =
{ .p_ctrl = &g_i2c_master0_ctrl, .p_cfg = &g_i2c_master0_cfg, .p_api = &g_i2c_master_on_iic };


is there any sample implementation?

PS: above hal_data.c is auto generated by e2studio.

  • > not sure when it will be used

    You should read FSP manual:
    https://renesas.github.io/rzv-fsp/index.html
    About callback, see:
    https://renesas.github.io/rzv-fsp/group___r_i_i_c___m_a_s_t_e_r.html
    stated as:
    A user callback function must be provided. This will be called from the interrupt service routine (ISR) upon RIIC transaction completion reporting the transaction status.

  • Thanks, for pointing to the document.

    is this implementation correct?

    /** Read the register_address value from the mlx90632
    *
    * i2c read is processor specific and this function expects to have address of mlx90632 known, as it operates purely on
    * register addresses.
    *
    * @note Needs to be implemented externally
    * @param[in] register_address Address of the register to be read from
    * @param[out] *value pointer to where read data can be written

    * @retval 0 for success
    * @retval <0 for failure
    */

    int32_t mlx90632_i2c_read(int16_t register_address, uint16_t *value)
    {
    uint16_t data_buffer = register_address;

    // Prepare the parameters for the write-read operation
    rm_comms_write_read_params_t write_read_params = {
    .p_write_data = (uint8_t *)&data_buffer,
    .write_data_bytes = sizeof(data_buffer),
    .p_read_data = (uint8_t *)value,
    .read_data_bytes = sizeof(*value)
    };

    // Perform the combined write-read operation
    fsp_err_t err = RM_COMMS_I2C_WriteRead(&g_comms_i2c_ctrl, write_read_params);

    if (err != FSP_SUCCESS)
    {
    return -1; // fail
    }

    return 0; // success
    }

    ________________________________________________

    // 2 times i2c write(one for register addr another for value)

    int32_t mlx90632_i2c_write(int16_t register_address, uint16_t value)

    {
    // Write the register address
    fsp_err_t err = RM_COMMS_I2C_Write(&g_comms_i2c_ctrl, (uint8_t *)&register_address, sizeof(register_address));

    if (err != FSP_SUCCESS)
    {
    return -1; // fail
    }

    // Write the 16-bit value
    err = RM_COMMS_I2C_Write(&g_comms_i2c_ctrl, (uint8_t *)&value, sizeof(value));

    if (err != FSP_SUCCESS)
    {
    return -1; // fail
    }

    return 0; // success
    }

  • Where can I can set the clock parameters for i2c. while doing a i2c_read() getting error in function : "

    static fsp_err_t iic_master_run_hw_master (iic_master_instance_ctrl_t * const p_ctrl)

    "

    uint32_t iic_clk = p0_clk / (1U << p_ctrl->p_reg->ICMR1_b.CKS);

    Looking the fsp documentation it says i2c clk is derived from P0 clk.