This commit is contained in:
2025-12-24 17:21:08 +09:00
parent a96323de19
commit 96dc62d8dc
2302 changed files with 455822 additions and 0 deletions

View File

@@ -0,0 +1,408 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright 2023-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : I2C driver
******************************************************************************/
/******************************************************************************
* @file i2c.c
* - Version : 0.02
* @brief I2C driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.11.2023 0.01 First Release
* : 24.06.2024 0.02 Remove pre-process branch of i2c3_read().
*****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <cpg.h>
#include <cpg_register.h>
#include <i2c.h>
#include <i2c_register.h>
#include <log.h>
#include <mem_io.h>
#include <pfc.h>
#include <pfc_register.h>
/* Setting value for PFC */
#define IP0SR4_SDA3 (0xF0000000U) /* bit[31:28] */
#define IP0SR4_SCL3 (0x0F000000U) /* bit[27:24] */
#define GPSR4_SDA3 (0x00000080U) /* bit7 */
#define GPSR4_SCL3 (0x00000040U) /* bit6 */
#define MODSEL4_SDA3 (0x00000080U) /* bit7 */
#define MODSEL4_SCL3 (0x00000040U) /* bit6 */
#define PUEN4_SDA3 (0x00000080U) /* bit7 */
#define PUEN4_SCL3 (0x00000040U) /* bit6 */
static void i2c3_init_pin_function(void);
void i2c3_init(void)
{
/*
* Module Standby setting for I2C3 is not nessesary
* because H/W initial value is 'Enables supply of the clock signal'.
*/
/* PFC setting for I2C3. */
i2c3_init_pin_function();
/* CDFD=0, HLSE=0, SME=0 */
mem_write32((uintptr_t)I2C3_ICCCR2, 0x00000000U);
/* SCGD=H'3, CDF=H'6 */
mem_write32((uintptr_t)I2C3_ICCCR, (SET_SCGD | SET_CDF));
mem_write32((uintptr_t)I2C3_ICSCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSAR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMAR, 0x00000000U);
}
/* End of function i2c3_init(void) */
static void i2c3_init_pin_function(void)
{
uint32_t data;
/* SDA3, SCL3 -> 0 */
data = mem_read32((uintptr_t)PFC_IP0SR4_RW);
data &= ~(IP0SR4_SDA3 | IP0SR4_SCL3);
pfc_reg_write(PFC_IP0SR4_RW, data);
/* SDA3, SCL3 -> 1 */
data = mem_read32((uintptr_t)PFC_GPSR4_RW);
data |= (GPSR4_SDA3 | GPSR4_SCL3);
pfc_reg_write(PFC_GPSR4_RW, data);
/* Select SDA3 and SCL3 to I2C mode */
data = mem_read32((uintptr_t)PFC_MODSEL4_RW);
data |= (MODSEL4_SDA3 | MODSEL4_SCL3);
pfc_reg_write(PFC_MODSEL4_RW, data);
/* SDA3, SCL3 -> 0 */
data = mem_read32((uintptr_t)PFC_PUEN4_RW);
data &= ~(PUEN4_SDA3 | PUEN4_SCL3);
pfc_reg_write(PFC_PUEN4_RW, data);
}
/* End of function i2c3_init_pin_function(void) */
void i2c3_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData)
{
uint32_t data;
uint32_t err_count = 0U;
uint32_t status;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS and MIE (initialize) */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
/* Set slave address */
slaveAdd &= ~FLG_RW; /* write mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set register address */
mem_write32((uintptr_t)I2C3_ICTXD, regAdd);
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* MDE(master data empty) & MAT(master address transmitted */
status = i2c3_err_check(FLAG_MDE, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("1:I2C data write error\n");
panic;
}
}
}
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
status = I2C_NG;
while(I2C_NG == status)
{
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= (FLAG_MNR | FLAG_MAL | FLAG_MST | FLAG_MDT | FLAG_MDR);
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) & MDT(master data transmitted) */
status = i2c3_err_check(FLAG_MDE, FLAG_MDT, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data write error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* send voltage */
mem_write32((uintptr_t)I2C3_ICTXD, setData);
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= (FLAG_MNR | FLAG_MAL | FLAG_MST | FLAG_MDR | FLAG_MAT);
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) & MDT(master data transmitted) */
status = i2c3_err_check(FLAG_MDE, FLAG_MDT, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data write error\n");
panic;
}
}
}
/* Set MDBS, MIE and FSB */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB)); /* stop condition */
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U); /* MST(master stop transmitted) clear */
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & FLAG_MST) != 0U) /* MST(master stop transmitted) */
{
break;
}
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
}
/* End of function i2c3_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData) */
void i2c3_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData)
{
uint32_t data;
uint32_t err_count = 0;
uint32_t status;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS and MIE (initialize) */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
/* Set slave address */
slaveAdd &= ~FLG_RW; /* write mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set register address */
mem_write32((uintptr_t)I2C3_ICTXD, regAdd);
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* MDE(master data empty) & MAT(master address transmitted */
status = i2c3_err_check(FLAG_MDE, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("1:I2C data read error\n");
panic;
}
}
}
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
status = I2C_NG;
while(I2C_NG == status)
{
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= 0x000000F6U;
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) */
status = i2c3_err_check(FLAG_MDE, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set slave address */
slaveAdd |= FLG_RW; /* read mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
/* MDR(master data recieved) & MAT(master address transmitted) */
status = i2c3_err_check(FLAG_MDR, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS, MIE and FSB */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB)); /* stop condition */
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= 0x000000FCU;
mem_write32((uintptr_t)I2C3_ICMSR, data);
status = i2c3_err_check(FLAG_MDR, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("4:I2C data read error\n");
panic;
}
}
if(I2C_OK == status)
{
*revData = mem_read32((uintptr_t)I2C3_ICRXD) & 0x000000FFU;
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U); /* MST(master stop transmitted) clear */
}
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & FLAG_MST) != 0U)
{
break;
}
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
}
/* End of function i2c3_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData) */
uint32_t i2c3_err_check(uint32_t first, uint32_t second, uint32_t error)
{
uint32_t data;
uint32_t status = I2C_OK;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & first) != 0U)
{
if((second == FLAG_NONE) || ((data & second) != 0U))
{
status = I2C_OK;
break;
}
}
if((data & error) != 0U)
{
mem_write32((uintptr_t)I2C3_ICMSR, ~error);
status = I2C_NG;
break;
}
}
return status;
}
/* End of function i2c3_err_check(uint32_t first, uint32_t second, uint32_t error) */
void i2c3_release(void)
{
mem_write32((uintptr_t)I2C3_ICCCR2, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICCCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSAR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMAR, 0x00000000U);
}
/* End of function i2c3_release(void) */