You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

446 lines
9.9 KiB

4 months ago
/**
******************************************************************************
* @copyright Copyright (C), 2016-2022, ConvenientPower. Co., Ltd.
* @file drv_i2c.h
* @version 1.0
* @author qing.cheng
* @date 2022-11-08
* @brief Header file of DRV_I2C_H module.
******************************************************************************
*/
#ifndef _DRV_I2C_H_
#define _DRV_I2C_H_
#include "core_comm.h"
#include "i2c_master_define.h"
#include "i2c1_master_define.h"
#include "clkctrl_define.h"
#include "extint_define.h"
#include "analog_define.h"
#include "drv_clock.h"
#include "stdbool.h"
#if 1
#define T_MEXT 5 /* ms */
#define T_SEXT 25 /* ms */
#define T_TIMEOUT 35 /* ms */
#define MS_TO_SMBUS_T(ms) ((ms) * (drv_clkctrl_sys_ctrl_mclk_get() / 1000) / 1024)
#define I2C_DELAY 1
#define I2C_WR 0x0
#define I2C_RD 0x1
/******************i2c0*******************/
#define I2C0_I2STAT (REG_I2C_MASTER_I2CSTA->word & 0xF8)
#define I2C0_I2STAT_RST (REG_I2C_MASTER_I2CSTA->word = 0xF8)
#define I2C0_SET_AA (REG_I2C_MASTER_I2CCON->bf.aa = 1)
#define I2C0_CLR_AA (REG_I2C_MASTER_I2CCON->bf.aa = 0)
#define I2C0_SI (REG_I2C_MASTER_I2CCON->bf.si)
#define I2C0_CLR_SI (REG_I2C_MASTER_I2CCON->bf.si = 0)
#define I2C0_STO (REG_I2C_MASTER_I2CCON->bf.sto)
#define I2C0_SET_STO (REG_I2C_MASTER_I2CCON->bf.sto = 1)
#define I2C0_CLR_STO (REG_I2C_MASTER_I2CCON->bf.sto = 0)
#define I2C0_SET_STA (REG_I2C_MASTER_I2CCON->bf.sta = 1)
#define I2C0_CLR_STA (REG_I2C_MASTER_I2CCON->bf.sta = 0)
#define I2C0_SET_I2CEN (REG_I2C_MASTER_I2CCON->bf.ens1 = 1)
#define I2C0_CLR_I2CEN (REG_I2C_MASTER_I2CCON->bf.ens1 = 0)
#define I2C0_I2DAT (REG_I2C_MASTER_I2CDAT->word)
/****************i2c1***********************/
#define I2C1_I2STAT (REG_I2C1_MASTER_I2CSTA->word & 0xF8)
#define I2C1_I2STAT_RST (REG_I2C1_MASTER_I2CSTA->word = 0xF8)
#define I2C1_SET_AA (REG_I2C1_MASTER_I2CCON->bf.aa = 1)
#define I2C1_CLR_AA (REG_I2C1_MASTER_I2CCON->bf.aa = 0)
#define I2C1_SI (REG_I2C1_MASTER_I2CCON->bf.si)
#define I2C1_CLR_SI (REG_I2C1_MASTER_I2CCON->bf.si = 0)
#define I2C1_STO (REG_I2C1_MASTER_I2CCON->bf.sto)
#define I2C1_SET_STO (REG_I2C1_MASTER_I2CCON->bf.sto = 1)
#define I2C1_CLR_STO (REG_I2C1_MASTER_I2CCON->bf.sto = 0)
#define I2C1_SET_STA (REG_I2C1_MASTER_I2CCON->bf.sta = 1)
#define I2C1_CLR_STA (REG_I2C1_MASTER_I2CCON->bf.sta = 0)
#define I2C1_SET_I2CEN (REG_I2C1_MASTER_I2CCON->bf.ens1 = 1)
#define I2C1_CLR_I2CEN (REG_I2C1_MASTER_I2CCON->bf.ens1 = 0)
#define I2C1_I2DAT (REG_I2C1_MASTER_I2CDAT->word)
#define I2C_STA_SLV_RX_ADDR_W_ACK 0x60
#define I2C_STA_SLV_RX_DATA_ACK 0x80
#define I2C_STA_SLV_RX_DATA_NACK 0x88
#define I2C_STA_SLV_RX_STO_RSTA 0xA0
#define I2C_STA_SLV_TX_ADDR_R_ACK 0xA8
#define I2C_STA_SLV_TX_DATA_ACK 0xB8
#define I2C_STA_SLV_TX_DATA_NACK 0xC0
#define I2C_STA_SLV_TX_LAST_DATA_ACK 0xC8
#define I2C_STA_MISC_BUS_ERR 0x00
#define I2C_STA_TO 0x07
#define REG_I2C0_I2CCON_ACK_NEXT (REG_I2C_MASTER_I2CCON_ENS1_MSK | REG_I2C_MASTER_I2CCON_AA_MSK)
#define REG_I2C0_I2CCON_NACK_NEXT (REG_I2C_MASTER_I2CCON_ENS1_MSK)
#define REG_I2C1_I2CCON_ACK_NEXT (REG_I2C1_MASTER_I2CCON_ENS1_MSK | REG_I2C1_MASTER_I2CCON_AA_MSK)
#define REG_I2C1_I2CCON_NACK_NEXT (REG_I2C1_MASTER_I2CCON_ENS1_MSK)
#define I2C_MASTER_I2CCON_STO_MSK (0x1 << 4)
#define I2C_SLAVE_R 0x01
#define I2C_SLAVE_W 0x02
typedef struct
{
uint8_t reg_data;//[TRANSMIT_BUF_SIZE];
uint32_t wr_addr;
uint8_t receive;//[RECEIVE_BUF_SIZE];
/*
* Private variables. They should never be accessed by i2c master.
*/
} __attribute__((packed)) s_ap_regs;
#define AP_REG_FUNC(_name, _func) \
{ ((uint32_t)(&(((s_ap_regs *)0)->_name)) + sizeof(((s_ap_regs *)0)->_name)), (_func) }
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
#define TRANSMIT_BUF_SIZE 4
#define RECEIVE_BUF_SIZE 4
typedef void(*i2c_drv_rw_cb)(uint8_t rw, uint8_t i2c_num);
typedef struct i2c_slave_msg_s
{
uint8_t *rx_buf;
uint8_t *tx_buf;
uint8_t *tx;
uint8_t *tx_end;
uint16_t rx_len;
uint16_t tx_len;
uint16_t rx_buf_size;
uint16_t tx_buf_size;
i2c_drv_rw_cb cb;
void(*tx_end_cb)(uint8_t i2c_num);
uint8_t slave_addr;
uint8_t i2c_num;
s_ap_regs ap_regs;
} i2c_slave_msg_s;
struct ap_reg_func_entry
{
uint8_t addr; /* Next address */
void (*func)(i2c_slave_msg_s *);
};
typedef enum
{
DRV_I2C_FREQ_5K,
DRV_I2C_FREQ_10K,
DRV_I2C_FREQ_20K,
DRV_I2C_FREQ_50K,
DRV_I2C_FREQ_100K,
DRV_I2C_FREQ_150K,
DRV_I2C_FREQ_300K,
DRV_I2C_FREQ_500K,
DRV_I2C_FREQ_NUM,
} drv_i2c_freq_e;
typedef enum
{
I2C_BW_8BIT = 1,
I2C_BW_16BIT = 2,
I2C_BW_32BIT = 4,
I2C_BW_MAX
} i2c_bw_e;
typedef enum
{
DRV_I2C0_NUM0 = 0,
DRV_I2C0_NUM1,
DRV_I2C0_NUM2,
DRV_I2C0_NUM3,
} drv_i2c0_num_e;
typedef enum
{
DRV_I2C1_NUM0 = 0,
DRV_I2C1_NUM1,
DRV_I2C1_NUM2,
} drv_i2c1_num_e;
void delay_us(int32_t us);
/*
* @brief drv_i2c_i2csta_get
* @param i2c_num
* @note
* @retval i2c stat
*/
uint8_t drv_i2c_i2csta_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2ccon_set_aa
* @param i2c_num
* @note
* @retval i2c stat
*/
void drv_i2c_i2ccon_set_aa(uint8_t i2c_num, bool enable);
/*
* @brief drv_i2c_i2ccon_si_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_i2ccon_si_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2ccon_clr_si
* @param i2c_num
* @note
* @retval i2ccon si state
*/
void drv_i2c_i2ccon_clr_si(uint8_t i2c_num);
/*
* @brief drv_i2c_i2ccon_sto_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_i2ccon_sto_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2ccon_stop_set
* @param i2c_num
* @param enable
* @note
* @retval i2ccon si state
*/
void drv_i2c_i2ccon_stop_set(uint8_t i2c_num, bool enable);
/*
* @brief drv_i2c_i2ccon_start_set
* @param i2c_num
* @param enable
* @note
* @retval i2ccon si state
*/
void drv_i2c_i2ccon_start_set(uint8_t i2c_num, bool enable);
/*
* @brief drv_i2c_i2ccon_start_set
* @param i2c_num
* @param enable
* @note
* @retval i2ccon si state
*/
void drv_i2c_i2ccon_ens1_set(uint8_t i2c_num, bool enable);
/*
* @brief drv_i2c_data_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_data_get(uint8_t i2c_num);
/*
* @brief drv_i2c_data_set
* @param i2c_num
* @note
* @retval i2ccon si state
*/
void drv_i2c_data_set(uint8_t i2c_num, uint8_t i2c_data);
/*
* @brief drv_i2c_i2cadr_set
* @param i2c_num
* @param i2c_addr
* @note
* @retval i2ccon si state
*/
void drv_i2c_i2cadr_set(uint8_t i2c_num, uint8_t i2c_addr);
/*
* @brief drv_i2c_data_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_i2cadr_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2ccon_ack_next_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_i2ccon_ack_next_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2con_nack_next_get
* @param i2c_num
* @note
* @retval i2ccon si state
*/
uint8_t drv_i2c_i2con_nack_next_get(uint8_t i2c_num);
/*
* @brief drv_i2c_i2cdat_write
* @param i2c_num
* @param data
* @note
* @retval null
*/
void drv_i2c_i2cdat_write(uint8_t i2c_num, uint8_t data);
/*
* @brief drv_i2c_i2cdat_read
* @param i2c_num
* @note
* @retval null
*/
uint8_t drv_i2c_i2cdat_read(uint8_t i2c_num);
/*
* @brief drv_analog_prot_word
* @param word
* @note
* @retval null
*/
void drv_i2c_i2ccon_word(uint8_t i2c_num, uint8_t value);
/*
* @brief drv_i2c_i2ccon_clr
* @param i2c_num
* @param clr
* @note
* @retval null
*/
void drv_i2c_i2ccon_clr(uint8_t i2c_num, uint8_t clr);
/*
* @brief drv_i2c_i2ccon_mask_set
* @param i2c_num
* @param value
* @note
* @retval null
*/
void drv_i2c_i2ccon_mask_set(uint8_t i2c_num, uint8_t value);
/*
* @brief drv_i2c_i2ccon_read
* @param i2c_num
* @note
* @retval i2c con value
*/
uint8_t drv_i2c_i2ccon_read(uint8_t i2c_num);
/*
* @brief drv_i2c_i2csta_read
* @param i2c_num
* @note
* @retval i2c sta value
*/
uint8_t drv_i2c_i2csta_read(uint8_t i2c_num);
/*
* @brief drv_i2c_int_clr
* @param i2c_num
* @note
* @retval NULL
*/
void drv_i2c_int_clr(uint8_t i2c_num);
/*
* @brief drv_i2c_set_freq
* @param i2c_num
* @param freq
* @note
* @retval null
*/
void drv_i2c_set_freq(uint8_t i2c_num, drv_i2c_freq_e freq);
/*
* @brief drv_i2c_init_smbus_timeout
* @param i2c_num
* @note
* @retval null
*/
void drv_i2c_init_smbus_timeout(uint8_t i2c_num);
/*
* @brief drv_i2c_master_init
* @param i2c_num
* @param i2c_scl_num
* @param i2c_sda_num
* @param freq
* @note
* @retval null
*/
void drv_i2c_master_init(uint8_t i2c_num, uint8_t i2c_scl_num, uint8_t i2c_sda_num, drv_i2c_freq_e freq);
/*
* @brief drv_i2c_slave_init
* @param i2c_num
* @param i2c_scl_num
* @param i2c_sda_num
* @param freq
* @note
* @retval null
*/
void drv_i2c_slave_init(uint8_t i2c_num, uint8_t i2c_scl_num, uint8_t i2c_sda_num, uint8_t slave_addr);
/*
* @brief drv_i2c_read_byte
* @param i2c_num
* @param Slave_addr
* @param reg_addr
* @param bw
* @param *u8DAT
* @param data_len
* @note
* @retval null
*/
bool drv_i2c_read_byte(uint8_t i2c_num, uint8_t Slave_addr, uint32_t reg_addr, i2c_bw_e bw, uint8_t *u8DAT, uint8_t data_len);
/*
* @brief i2c_write_byte
* @param i2c_num
* @param Slave_addr
* @param reg_addr
* @param bw
* @param *u8DAT
* @param data_len
* @note
* @retval null
*/
bool drv_i2c_write_byte(uint8_t i2c_num, uint8_t Slave_addr, uint32_t reg_addr, i2c_bw_e bw, uint8_t *u8DAT, uint8_t data_len);
/*
* @brief drv_i2c_pin_set
* @param i2c_num
* @param i2c_scl_num
* @param i2c_sda_num
* @note
* @retval null
*/
void drv_i2c_pin_set(uint8_t i2c_num, uint8_t i2c_scl_num, uint8_t i2c_sda_num);
/*
* @brief i2c_handler
* @param i2c_slave
* @note
* @retval null
*/
void i2c_handler(i2c_slave_msg_s *i2c_slave);
#endif
#endif