Merge branch 'feature/support_i2c_on_h2' into 'master'

i2c: support i2c on esp32h2

Closes IDF-6233 and IDF-6689

See merge request espressif/esp-idf!21982
This commit is contained in:
Kevin (Lao Kaiyao) 2023-02-02 15:18:37 +08:00
commit 6cef87fea3
19 changed files with 1038 additions and 303 deletions

View File

@ -22,7 +22,9 @@ extern "C" {
#include "soc/soc_caps.h"
#include "hal/i2c_types.h"
#define I2C_APB_CLK_FREQ APB_CLK_FREQ /*!< I2C source clock is APB clock, 80MHz */
#if SOC_I2C_SUPPORT_APB
#define I2C_APB_CLK_FREQ _Pragma ("GCC warning \"'I2C_APB_CLK_FREQ' macro is deprecated\"") (APB_CLK_FREQ) /*!< I2C source clock is APB clock, 80MHz, deprecated */
#endif
// I2C clk flags for users to use, can be expanded in the future.
#define I2C_SCLK_SRC_FLAG_FOR_NOMAL (0) /*!< Any one clock source that is available for the specified frequency may be choosen*/

View File

@ -2,7 +2,8 @@
components/esp_lcd/test_apps/i2c_lcd:
disable:
- if: SOC_I2C_SUPPORTED != 1
- if: SOC_I2C_SUPPORTED != 1 or IDF_TARGET == "esp32h2"
reason: LCD has not been supported on esp32h2, IDF-6213
components/esp_lcd/test_apps/i80_lcd:
disable:

View File

@ -0,0 +1,948 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for I2C register operations
#pragma once
#include <stdbool.h>
#include "hal/misc.h"
#include "soc/i2c_periph.h"
#include "soc/soc_caps.h"
#include "soc/i2c_struct.h"
#include "soc/pcr_struct.h"
#include "hal/i2c_types.h"
#include "soc/clk_tree_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief I2C hardware cmd register fields.
*/
typedef union {
struct {
uint32_t byte_num: 8,
ack_en: 1,
ack_exp: 1,
ack_val: 1,
op_code: 3,
reserved14: 17,
done: 1;
};
uint32_t val;
} i2c_ll_hw_cmd_t;
// I2C operation mode command
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
#define I2C_LL_CMD_READ 3 /*!<I2C read command */
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
#define I2C_LL_CMD_END 4 /*!<I2C end command */
typedef enum {
I2C_INTR_NACK = (1 << 10),
I2C_INTR_TIMEOUT = (1 << 8),
I2C_INTR_MST_COMPLETE = (1 << 7),
I2C_INTR_ARBITRATION = (1 << 5),
I2C_INTR_END_DETECT = (1 << 3),
I2C_INTR_ST_TO = (1 << 13),
} i2c_ll_master_intr_t;
typedef enum {
I2C_INTR_TXFIFO_WM = (1 << 1),
I2C_INTR_RXFIFO_WM = (1 << 0),
I2C_INTR_SLV_COMPLETE = (1 << 7),
I2C_INTR_START = (1 << 15),
} i2c_ll_slave_intr_t;
// Get the I2C hardware instance
#define I2C_LL_GET_HW(i2c_num) (i2c_num == 0 ? (&I2C0) : (&I2C1))
#define I2C_LL_GET_NUM(hw) (hw == &I2C0 ? 0 : 1)
#define I2C_LL_MASTER_EVENT_INTR (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
/**
* @brief Calculate I2C bus frequency
* Note that the clock accuracy is affected by the external pull-up resistor,
* here we try to to calculate a configuration parameter which is close to the required clock.
* But in I2C communication, the clock accuracy is not very concerned.
*
* @param source_clk I2C source clock
* @param bus_freq I2C bus frequency
* @param clk_cal Pointer to accept the clock configuration
*
* @return None
*/
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
{
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
uint32_t sclk_freq = source_clk / clkm_div;
uint32_t half_cycle = sclk_freq / bus_freq / 2;
//SCL
clk_cal->clkm_div = clkm_div;
clk_cal->scl_low = half_cycle;
// default, scl_wait_high < scl_high
// Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency
// according to some hardware behaviors.
clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4);
clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high;
clk_cal->sda_hold = half_cycle / 4;
clk_cal->sda_sample = half_cycle / 2 + clk_cal->scl_wait_high;
clk_cal->setup = half_cycle;
clk_cal->hold = half_cycle;
//default we set the timeout value to about 10 bus cycles
// log(20*half_cycle)/log(2) = log(half_cycle)/log(2) + log(20)/log(2)
clk_cal->tout = (int)(sizeof(half_cycle) * 8 - __builtin_clz(5 * half_cycle)) + 2;
}
/**
* @brief Update I2C configuration
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_update(i2c_dev_t *hw)
{
hw->ctr.conf_upgate = 1;
}
/**
* @brief Configure the I2C bus timing related register.
*
* @param hw Beginning address of the peripheral registers
* @param bus_cfg Pointer to the data structure holding the register configuration.
*
* @return None
*/
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c[I2C_LL_GET_NUM(hw)].i2c_sclk_conf, i2c_sclk_div_num, bus_cfg->clkm_div - 1);
/* Set div_a and div_b to 0, as it's not necessary to use them */
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c[I2C_LL_GET_NUM(hw)].i2c_sclk_conf, i2c_sclk_div_a, 0);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c[I2C_LL_GET_NUM(hw)].i2c_sclk_conf, i2c_sclk_div_b, 0);
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
* However, according to the practical measurement and some hardware behaviour, if wait_high_period and scl_high minus one.
* The SCL frequency would be a little higher than expected. Therefore, the solution
* here is not to minus scl_high as well as scl_wait high, and the frequency will be absolutely accurate to all frequency
* to some extent. */
hw->scl_low_period.scl_low_period = bus_cfg->scl_low - 1;
hw->scl_high_period.scl_high_period = bus_cfg->scl_high;
hw->scl_high_period.scl_wait_high_period = bus_cfg->scl_wait_high;
//sda sample
hw->sda_hold.sda_hold_time = bus_cfg->sda_hold - 1;
hw->sda_sample.sda_sample_time = bus_cfg->sda_sample - 1;
//setup
hw->scl_rstart_setup.scl_rstart_setup_time = bus_cfg->setup - 1;
hw->scl_stop_setup.scl_stop_setup_time = bus_cfg->setup - 1;
//hold
hw->scl_start_hold.scl_start_hold_time = bus_cfg->hold - 1;
hw->scl_stop_hold.scl_stop_hold_time = bus_cfg->hold - 1;
hw->to.time_out_value = bus_cfg->tout;
hw->to.time_out_en = 1;
}
/**
* @brief Reset I2C txFIFO
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw)
{
hw->fifo_conf.tx_fifo_rst = 1;
hw->fifo_conf.tx_fifo_rst = 0;
}
/**
* @brief Reset I2C rxFIFO
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw)
{
hw->fifo_conf.rx_fifo_rst = 1;
hw->fifo_conf.rx_fifo_rst = 0;
}
/**
* @brief Configure I2C SCL timing
*
* @param hw Beginning address of the peripheral registers
* @param hight_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
*
* @return None.
*/
static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period)
{
hw->scl_low_period.scl_low_period = low_period - 1;
hw->scl_high_period.scl_high_period = hight_period - 10;
hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.scl_high_period;
}
/**
* @brief Clear I2C interrupt status
*
* @param hw Beginning address of the peripheral registers
* @param mask Interrupt mask needs to be cleared
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
{
hw->int_clr.val = mask;
}
/**
* @brief Enable I2C interrupt
*
* @param hw Beginning address of the peripheral registers
* @param mask Interrupt mask needs to be enabled
*
* @return None
*/
static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
{
hw->int_ena.val |= mask;
}
/**
* @brief Disable I2C interrupt
*
* @param hw Beginning address of the peripheral registers
* @param mask Interrupt mask needs to be disabled
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
{
hw->int_ena.val &= (~mask);
}
/**
* @brief Get I2C interrupt status
*
* @param hw Beginning address of the peripheral registers
*
* @return I2C interrupt status
*/
__attribute__((always_inline))
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_status.val;
}
/**
* @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode
*
* @param hw Beginning address of the peripheral registers
* @param fifo_mode_en Set true to enable FIFO access mode, else, set it false
*
* @return None
*/
static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en)
{
hw->fifo_conf.nonfifo_en = fifo_mode_en ? 0 : 1;
}
/**
* @brief Configure I2C timeout
*
* @param hw Beginning address of the peripheral registers
* @param tout_num The I2C timeout value needs to be set (2^tout in core clock cycle)
*
* @return None
*/
static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout)
{
hw->to.time_out_value = tout;
}
/**
* @brief Configure I2C slave address
*
* @param hw Beginning address of the peripheral registers
* @param slave_addr I2C slave address needs to be set
* @param addr_10bit_en Set true to enable 10-bit slave address mode, set false to enable 7-bit address mode
*
* @return None
*/
static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, bool addr_10bit_en)
{
hw->slave_addr.slave_addr = slave_addr;
hw->slave_addr.addr_10bit_en = addr_10bit_en;
}
/**
* @brief Write I2C hardware command register
*
* @param hw Beginning address of the peripheral registers
* @param cmd I2C hardware command
* @param cmd_idx The index of the command register, should be less than 16
*
* @return None
*/
static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int cmd_idx)
{
hw->command[cmd_idx].val = cmd.val;
}
/**
* @brief Configure I2C start timing
*
* @param hw Beginning address of the peripheral registers
* @param start_setup The start condition setup period (in core clock cycle)
* @param start_hold The start condition hold period (in core clock cycle)
*
* @return None
*/
static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold)
{
hw->scl_rstart_setup.scl_rstart_setup_time = start_setup;
hw->scl_start_hold.scl_start_hold_time = start_hold - 1;
}
/**
* @brief Configure I2C stop timing
*
* @param hw Beginning address of the peripheral registers
* @param stop_setup The stop condition setup period (in core clock cycle)
* @param stop_hold The stop condition hold period (in core clock cycle)
*
* @return None
*/
static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold)
{
hw->scl_stop_setup.scl_stop_setup_time = stop_setup;
hw->scl_stop_hold.scl_stop_hold_time = stop_hold;
}
/**
* @brief Configure I2C stop timing
*
* @param hw Beginning address of the peripheral registers
* @param sda_sample The SDA sample time (in core clock cycle)
* @param sda_hold The SDA hold time (in core clock cycle)
*
* @return None
*/
static inline void i2c_ll_set_sda_timing(i2c_dev_t *hw, int sda_sample, int sda_hold)
{
hw->sda_hold.sda_hold_time = sda_hold;
hw->sda_sample.sda_sample_time = sda_sample;
}
/**
* @brief Set I2C txFIFO empty threshold
*
* @param hw Beginning address of the peripheral registers
* @param empty_thr The txFIFO empty threshold
*
* @return None
*/
static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr)
{
hw->fifo_conf.txfifo_wm_thrhd = empty_thr;
}
/**
* @brief Set I2C rxFIFO full threshold
*
* @param hw Beginning address of the peripheral registers
* @param full_thr The rxFIFO full threshold
*
* @return None
*/
static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr)
{
hw->fifo_conf.rxfifo_wm_thrhd = full_thr;
}
/**
* @brief Set the I2C data mode, LSB or MSB
*
* @param hw Beginning address of the peripheral registers
* @param tx_mode Tx data bit mode
* @param rx_mode Rx data bit mode
*
* @return None
*/
static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode)
{
hw->ctr.tx_lsb_first = tx_mode;
hw->ctr.rx_lsb_first = rx_mode;
}
/**
* @brief Get the I2C data mode
*
* @param hw Beginning address of the peripheral registers
* @param tx_mode Pointer to accept the received bytes mode
* @param rx_mode Pointer to accept the sended bytes mode
*
* @return None
*/
static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode)
{
*tx_mode = hw->ctr.tx_lsb_first;
*rx_mode = hw->ctr.rx_lsb_first;
}
/**
* @brief Get I2C sda timing configuration
*
* @param hw Beginning address of the peripheral registers
* @param sda_sample Pointer to accept the SDA sample timing configuration
* @param sda_hold Pointer to accept the SDA hold timing configuration
*
* @return None
*/
static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sda_hold)
{
*sda_hold = hw->sda_hold.sda_hold_time;
*sda_sample = hw->sda_sample.sda_sample_time;
}
/**
* @brief Get the I2C hardware version
*
* @param hw Beginning address of the peripheral registers
*
* @return The I2C hardware version
*/
static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw)
{
return hw->date.date;
}
/**
* @brief Check if the I2C bus is busy
*
* @param hw Beginning address of the peripheral registers
*
* @return True if I2C state machine is busy, else false will be returned
*/
static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw)
{
return hw->sr.bus_busy;
}
/**
* @brief Check if I2C is master mode
*
* @param hw Beginning address of the peripheral registers
*
* @return True if I2C is master mode, else false will be returned
*/
static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
{
return hw->ctr.ms_mode;
}
/**
* @brief Get the rxFIFO readable length
*
* @param hw Beginning address of the peripheral registers
*
* @return RxFIFO readable length
*/
__attribute__((always_inline))
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
{
*length = hw->sr.rxfifo_cnt;
}
/**
* @brief Get I2C txFIFO writable length
*
* @param hw Beginning address of the peripheral registers
*
* @return TxFIFO writable length
*/
__attribute__((always_inline))
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
{
*length = SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt;
}
/**
* @brief Get I2C timeout configuration
*
* @param hw Beginning address of the peripheral registers
*
* @return The I2C timeout value
*/
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
{
*timeout = hw->to.time_out_value;
}
/**
* @brief Start I2C transfer
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_trans_start(i2c_dev_t *hw)
{
hw->ctr.trans_start = 1;
}
/**
* @brief Get I2C start timing configuration
*
* @param hw Beginning address of the peripheral registers
* @param setup_time Pointer to accept the start condition setup period
* @param hold_time Pointer to accept the start condition hold period
*
* @return None
*/
static inline void i2c_ll_get_start_timing(i2c_dev_t *hw, int *setup_time, int *hold_time)
{
*setup_time = hw->scl_rstart_setup.scl_rstart_setup_time;
*hold_time = hw->scl_start_hold.scl_start_hold_time + 1;
}
/**
* @brief Get I2C stop timing configuration
*
* @param hw Beginning address of the peripheral registers
* @param setup_time Pointer to accept the stop condition setup period
* @param hold_time Pointer to accept the stop condition hold period
*
* @return None
*/
static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *hold_time)
{
*setup_time = hw->scl_stop_setup.scl_stop_setup_time;
*hold_time = hw->scl_stop_hold.scl_stop_hold_time;
}
/**
* @brief Get I2C SCL timing configuration
*
* @param hw Beginning address of the peripheral registers
* @param high_period Pointer to accept the SCL high period
* @param low_period Pointer to accept the SCL low period
*
* @return None
*/
static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *low_period)
{
*high_period = hw->scl_high_period.scl_high_period + hw->scl_high_period.scl_wait_high_period;
*low_period = hw->scl_low_period.scl_low_period + 1;
}
/**
* @brief Write the I2C hardware txFIFO
*
* @param hw Beginning address of the peripheral registers
* @param ptr Pointer to data buffer
* @param len Amount of data needs to be writen
*
* @return None.
*/
__attribute__((always_inline))
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
{
for (int i = 0; i< len; i++) {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]);
}
}
/**
* @brief Read the I2C hardware rxFIFO
*
* @param hw Beginning address of the peripheral registers
* @param ptr Pointer to data buffer
* @param len Amount of data needs read
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
{
for(int i = 0; i < len; i++) {
ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata);
}
}
/**
* @brief Configure I2C hardware filter
*
* @param hw Beginning address of the peripheral registers
* @param filter_num If the glitch period on the line is less than this value, it can be filtered out
* If `filter_num == 0`, the filter will be disabled
*
* @return None
*/
static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
{
if (filter_num > 0) {
hw->filter_cfg.scl_filter_thres = filter_num;
hw->filter_cfg.sda_filter_thres = filter_num;
hw->filter_cfg.scl_filter_en = 1;
hw->filter_cfg.sda_filter_en = 1;
} else {
hw->filter_cfg.scl_filter_en = 0;
hw->filter_cfg.sda_filter_en = 0;
}
}
/**
* @brief Get I2C hardware filter configuration
*
* @param hw Beginning address of the peripheral registers
*
* @return The hardware filter configuration
*/
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
{
*filter_conf = hw->filter_cfg.scl_filter_thres;
}
/**
* @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
{
// fsm_rst is a self cleared bit.
hw->ctr.fsm_rst = 1;
}
/**
* @brief Clear I2C bus, when the slave is stuck in a deadlock and keeps pulling the bus low,
* master can controls the SCL bus to generate 9 CLKs.
*
* Note: The master cannot detect if deadlock happens, but when the scl_st_to interrupt is generated, a deadlock may occur.
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
{
hw->scl_sp_conf.scl_rst_slv_num = 9;
hw->scl_sp_conf.scl_rst_slv_en = 1;
hw->ctr.conf_upgate = 1;
// hardward will clear scl_rst_slv_en after sending SCL pulses,
// and we should set conf_upgate bit to synchronize register value.
while (hw->scl_sp_conf.scl_rst_slv_en);
hw->ctr.conf_upgate = 1;
}
/**
* @brief Set I2C source clock
*
* @param hw Beginning address of the peripheral registers
* @param src_clk Source clock of the I2C
*
* @return None
*/
static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_clk)
{
// src_clk : (1) for RTC_CLK, (0) for XTAL
PCR.i2c[I2C_LL_GET_NUM(hw)].i2c_sclk_conf.i2c_sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
}
/**
* @brief Enable I2C peripheral controller clock
*
* @param dev Peripheral instance address
* @param en True to enable, False to disable
*/
static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
{
(void)hw;
PCR.i2c[I2C_LL_GET_NUM(hw)].i2c_sclk_conf.i2c_sclk_en = en;
}
/**
* @brief Init I2C master
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_init(i2c_dev_t *hw)
{
typeof(hw->ctr) ctrl_reg;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
}
/**
* @brief Init I2C slave
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_init(i2c_dev_t *hw)
{
typeof(hw->ctr) ctrl_reg;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
hw->fifo_conf.fifo_addr_cfg_en = 0;
}
/**
* @brief Set whether slave should auto start, or only start with start signal from master
*
* @param hw Beginning address of the peripheral registers
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
*/
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
{
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
}
/**
* @brief Get I2C interrupt status register address
*/
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
{
return &dev->int_status;
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I2C master TX interrupt bitmap
#define I2C_LL_MASTER_TX_INT (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
// I2C master RX interrupt bitmap
#define I2C_LL_MASTER_RX_INT (I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
// I2C slave TX interrupt bitmap
#define I2C_LL_SLAVE_TX_INT (I2C_TXFIFO_WM_INT_ENA_M)
// I2C slave RX interrupt bitmap
#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_WM_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M)
// I2C max timeout value
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
/**
* @brief I2C interrupt event
*/
typedef enum {
I2C_INTR_EVENT_ERR,
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
} i2c_intr_event_t;
/**
* @brief Configure I2C SCL timing
*
* @param hw Beginning address of the peripheral registers
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
* @param wait_high_period The I2C SCL wait rising edge period.
*
* @return None.
*/
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
{
hw->scl_low_period.scl_low_period = low_period;
hw->scl_high_period.scl_high_period = high_period;
hw->scl_high_period.scl_wait_high_period = wait_high_period;
}
/**
* @brief Get I2C SCL timing configuration
*
* @param hw Beginning address of the peripheral registers
* @param high_period Pointer to accept the SCL high period
* @param low_period Pointer to accept the SCL low period
*
* @return None
*/
static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, int *low_period, int *wait_high_period)
{
*high_period = hw->scl_high_period.scl_high_period;
*wait_high_period = hw->scl_high_period.scl_wait_high_period;
*low_period = hw->scl_low_period.scl_low_period;
}
/**
* @brief Get I2C master interrupt event
*
* @param hw Beginning address of the peripheral registers
* @param event Pointer to accept the interrupt event
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
{
i2c_int_status_reg_t int_sts = hw->int_status;
if (int_sts.arbitration_lost_int_st) {
*event = I2C_INTR_EVENT_ARBIT_LOST;
} else if (int_sts.nack_int_st) {
*event = I2C_INTR_EVENT_NACK;
} else if (int_sts.time_out_int_st) {
*event = I2C_INTR_EVENT_TOUT;
} else if (int_sts.end_detect_int_st) {
*event = I2C_INTR_EVENT_END_DET;
} else if (int_sts.trans_complete_int_st) {
*event = I2C_INTR_EVENT_TRANS_DONE;
} else {
*event = I2C_INTR_EVENT_ERR;
}
}
/**
* @brief Get I2C slave interrupt event
*
* @param hw Beginning address of the peripheral registers
* @param event Pointer to accept the interrupt event
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
{
typeof(hw->int_status) int_sts = hw->int_status;
if (int_sts.txfifo_wm_int_st) {
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
} else if (int_sts.trans_complete_int_st) {
*event = I2C_INTR_EVENT_TRANS_DONE;
} else if (int_sts.rxfifo_wm_int_st) {
*event = I2C_INTR_EVENT_RXFIFO_FULL;
} else {
*event = I2C_INTR_EVENT_ERR;
}
}
/**
* @brief Enable I2C master TX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
{
hw->int_clr.val = UINT32_MAX;
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
}
/**
* @brief Enable I2C master RX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
{
hw->int_clr.val = UINT32_MAX;
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
}
/**
* @brief Disable I2C master TX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
{
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
}
/**
* @brief Disable I2C master RX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
{
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
}
/**
* @brief
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
{
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
}
/**
* @brief Enable I2C slave RX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_enable_rx_it(i2c_dev_t *hw)
{
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
}
/**
* @brief Disable I2C slave TX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
{
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
}
/**
* @brief Disable I2C slave RX interrupt
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw)
{
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
}
#ifdef __cplusplus
}
#endif

View File

@ -281,9 +281,9 @@ typedef enum {
* @brief Type of I2C clock source.
*/
typedef enum {
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default source clock */
} soc_periph_i2c_clk_src_t;

View File

@ -55,6 +55,10 @@ config SOC_LEDC_SUPPORTED
bool
default y
config SOC_I2C_SUPPORTED
bool
default y
config SOC_SYSTIMER_SUPPORTED
bool
default y
@ -269,12 +273,16 @@ config SOC_DEDIC_PERIPH_ALWAYS_ENABLE
config SOC_I2C_NUM
int
default 1
default 2
config SOC_I2C_FIFO_LEN
int
default 32
config SOC_I2C_SUPPORT_SLAVE
bool
default y
config SOC_I2C_SUPPORT_HW_CLR_BUS
bool
default y
@ -283,10 +291,6 @@ config SOC_I2C_SUPPORT_XTAL
bool
default y
config SOC_I2C_SUPPORT_RTC
bool
default y
config SOC_I2S_NUM
int
default 1

View File

@ -315,9 +315,9 @@ typedef enum {
* @brief Type of I2C clock source.
*/
typedef enum {
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default source clock */
} soc_periph_i2c_clk_src_t;
/////////////////////////////////////////////////SPI////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -909,195 +909,29 @@ typedef union {
/** Group: Command registers */
/** Type of comd0 register
* I2C command register 0
/** Type of comd register
* I2C command register 0~7
*/
typedef union {
struct {
/** command0 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 0. It consists of three parts:
/** command : R/W; bitpos: [13:0]; default: 0;
* This is the content of command. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command0:14;
uint32_t command:14;
uint32_t reserved_14:17;
/** command0_done : R/W/SS; bitpos: [31]; default: 0;
* When command 0 is done in I2C Master mode, this bit changes to high
/** command_done : R/W/SS; bitpos: [31]; default: 0;
* When command is done in I2C Master mode, this bit changes to high
* level.
*/
uint32_t command0_done:1;
uint32_t command_done:1;
};
uint32_t val;
} i2c_comd0_reg_t;
/** Type of comd1 register
* I2C command register 1
*/
typedef union {
struct {
/** command1 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 1. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command1:14;
uint32_t reserved_14:17;
/** command1_done : R/W/SS; bitpos: [31]; default: 0;
* When command 1 is done in I2C Master mode, this bit changes to high
* level.
*/
uint32_t command1_done:1;
};
uint32_t val;
} i2c_comd1_reg_t;
/** Type of comd2 register
* I2C command register 2
*/
typedef union {
struct {
/** command2 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 2. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command2:14;
uint32_t reserved_14:17;
/** command2_done : R/W/SS; bitpos: [31]; default: 0;
* When command 2 is done in I2C Master mode, this bit changes to high
* Level.
*/
uint32_t command2_done:1;
};
uint32_t val;
} i2c_comd2_reg_t;
/** Type of comd3 register
* I2C command register 3
*/
typedef union {
struct {
/** command3 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 3. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command3:14;
uint32_t reserved_14:17;
/** command3_done : R/W/SS; bitpos: [31]; default: 0;
* When command 3 is done in I2C Master mode, this bit changes to high
* level.
*/
uint32_t command3_done:1;
};
uint32_t val;
} i2c_comd3_reg_t;
/** Type of comd4 register
* I2C command register 4
*/
typedef union {
struct {
/** command4 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 4. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command4:14;
uint32_t reserved_14:17;
/** command4_done : R/W/SS; bitpos: [31]; default: 0;
* When command 4 is done in I2C Master mode, this bit changes to high
* level.
*/
uint32_t command4_done:1;
};
uint32_t val;
} i2c_comd4_reg_t;
/** Type of comd5 register
* I2C command register 5
*/
typedef union {
struct {
/** command5 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 5. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command5:14;
uint32_t reserved_14:17;
/** command5_done : R/W/SS; bitpos: [31]; default: 0;
* When command 5 is done in I2C Master mode, this bit changes to high level.
*/
uint32_t command5_done:1;
};
uint32_t val;
} i2c_comd5_reg_t;
/** Type of comd6 register
* I2C command register 6
*/
typedef union {
struct {
/** command6 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 6. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command6:14;
uint32_t reserved_14:17;
/** command6_done : R/W/SS; bitpos: [31]; default: 0;
* When command 6 is done in I2C Master mode, this bit changes to high level.
*/
uint32_t command6_done:1;
};
uint32_t val;
} i2c_comd6_reg_t;
/** Type of comd7 register
* I2C command register 7
*/
typedef union {
struct {
/** command7 : R/W; bitpos: [13:0]; default: 0;
* This is the content of command 7. It consists of three parts:
* op_code is the command, 0: RSTART, 1: WRITE, 2: READ, 3: STOP, 4: END.
* Byte_num represents the number of bytes that need to be sent or received.
* ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C cmd
* structure for more
* Information.
*/
uint32_t command7:14;
uint32_t reserved_14:17;
/** command7_done : R/W/SS; bitpos: [31]; default: 0;
* When command 7 is done in I2C Master mode, this bit changes to high level.
*/
uint32_t command7_done:1;
};
uint32_t val;
} i2c_comd7_reg_t;
} i2c_comd_reg_t;
/** Group: Version register */
/** Type of date register
@ -1142,7 +976,7 @@ typedef union {
} i2c_rxfifo_start_addr_reg_t;
typedef struct {
typedef struct i2c_dev_t {
volatile i2c_scl_low_period_reg_t scl_low_period;
volatile i2c_ctr_reg_t ctr;
volatile i2c_sr_reg_t sr;
@ -1165,14 +999,7 @@ typedef struct {
volatile i2c_scl_stop_setup_reg_t scl_stop_setup;
volatile i2c_filter_cfg_reg_t filter_cfg;
volatile i2c_clk_conf_reg_t clk_conf;
volatile i2c_comd0_reg_t comd0;
volatile i2c_comd1_reg_t comd1;
volatile i2c_comd2_reg_t comd2;
volatile i2c_comd3_reg_t comd3;
volatile i2c_comd4_reg_t comd4;
volatile i2c_comd5_reg_t comd5;
volatile i2c_comd6_reg_t comd6;
volatile i2c_comd7_reg_t comd7;
volatile i2c_comd_reg_t command[8];
volatile i2c_scl_st_time_out_reg_t scl_st_time_out;
volatile i2c_scl_main_st_time_out_reg_t scl_main_st_time_out;
volatile i2c_scl_sp_conf_reg_t scl_sp_conf;

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -201,111 +201,58 @@ typedef union {
uint32_t val;
} pcr_mspi_clk_conf_reg_t;
/** Type of i2c0_conf register
/** Type of i2c_conf register
* I2C configuration register
*/
typedef union {
struct {
/** i2c0_clk_en : R/W; bitpos: [0]; default: 1;
/** i2c_clk_en : R/W; bitpos: [0]; default: 1;
* Set 1 to enable i2c apb clock
*/
uint32_t i2c0_clk_en:1;
/** i2c0_rst_en : R/W; bitpos: [1]; default: 0;
uint32_t i2c_clk_en:1;
/** i2c_rst_en : R/W; bitpos: [1]; default: 0;
* Set 0 to reset i2c module
*/
uint32_t i2c0_rst_en:1;
/** i2c0_ready : RO; bitpos: [2]; default: 1;
* Query this field after reset i2c0 module
uint32_t i2c_rst_en:1;
/** i2c_ready : RO; bitpos: [2]; default: 1;
* Query this field after reset i2c module
*/
uint32_t i2c0_ready:1;
uint32_t i2c_ready:1;
uint32_t reserved_3:29;
};
uint32_t val;
} pcr_i2c0_conf_reg_t;
} pcr_i2c_conf_reg_t;
/** Type of i2c0_sclk_conf register
/** Type of i2c_sclk_conf register
* I2C_SCLK configuration register
*/
typedef union {
struct {
/** i2c0_sclk_div_a : R/W; bitpos: [5:0]; default: 0;
/** i2c_sclk_div_a : R/W; bitpos: [5:0]; default: 0;
* The denominator of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c0_sclk_div_a:6;
/** i2c0_sclk_div_b : R/W; bitpos: [11:6]; default: 0;
uint32_t i2c_sclk_div_a:6;
/** i2c_sclk_div_b : R/W; bitpos: [11:6]; default: 0;
* The numerator of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c0_sclk_div_b:6;
/** i2c0_sclk_div_num : R/W; bitpos: [19:12]; default: 0;
uint32_t i2c_sclk_div_b:6;
/** i2c_sclk_div_num : R/W; bitpos: [19:12]; default: 0;
* The integral part of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c0_sclk_div_num:8;
/** i2c0_sclk_sel : R/W; bitpos: [20]; default: 0;
uint32_t i2c_sclk_div_num:8;
/** i2c_sclk_sel : R/W; bitpos: [20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: FOSC.
*/
uint32_t i2c0_sclk_sel:1;
uint32_t i2c_sclk_sel:1;
uint32_t reserved_21:1;
/** i2c0_sclk_en : R/W; bitpos: [22]; default: 1;
/** i2c_sclk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable i2c function clock
*/
uint32_t i2c0_sclk_en:1;
uint32_t i2c_sclk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_i2c0_sclk_conf_reg_t;
/** Type of i2c1_conf register
* I2C configuration register
*/
typedef union {
struct {
/** i2c1_clk_en : R/W; bitpos: [0]; default: 1;
* Set 1 to enable i2c apb clock
*/
uint32_t i2c1_clk_en:1;
/** i2c1_rst_en : R/W; bitpos: [1]; default: 0;
* Set 0 to reset i2c module
*/
uint32_t i2c1_rst_en:1;
/** i2c1_ready : RO; bitpos: [2]; default: 1;
* Query this field after reset i2c1 module
*/
uint32_t i2c1_ready:1;
uint32_t reserved_3:29;
};
uint32_t val;
} pcr_i2c1_conf_reg_t;
/** Type of i2c1_sclk_conf register
* I2C_SCLK configuration register
*/
typedef union {
struct {
/** i2c1_sclk_div_a : R/W; bitpos: [5:0]; default: 0;
* The denominator of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c1_sclk_div_a:6;
/** i2c1_sclk_div_b : R/W; bitpos: [11:6]; default: 0;
* The numerator of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c1_sclk_div_b:6;
/** i2c1_sclk_div_num : R/W; bitpos: [19:12]; default: 0;
* The integral part of the frequency divider factor of the i2c function clock.
*/
uint32_t i2c1_sclk_div_num:8;
/** i2c1_sclk_sel : R/W; bitpos: [20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: FOSC.
*/
uint32_t i2c1_sclk_sel:1;
uint32_t reserved_21:1;
/** i2c1_sclk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable i2c function clock
*/
uint32_t i2c1_sclk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_i2c1_sclk_conf_reg_t;
} pcr_i2c_sclk_conf_reg_t;
/** Type of uhci_conf register
* UHCI configuration register
@ -2037,6 +1984,14 @@ typedef union {
} pcr_date_reg_t;
/**
* @brief The struct of I2C configuration registers
*/
typedef struct {
pcr_i2c_conf_reg_t i2c_conf;
pcr_i2c_sclk_conf_reg_t i2c_sclk_conf;
} pcr_i2c_reg_t;
typedef struct {
volatile pcr_uart0_conf_reg_t uart0_conf;
volatile pcr_uart0_sclk_conf_reg_t uart0_sclk_conf;
@ -2046,10 +2001,7 @@ typedef struct {
volatile pcr_uart1_pd_ctrl_reg_t uart1_pd_ctrl;
volatile pcr_mspi_conf_reg_t mspi_conf;
volatile pcr_mspi_clk_conf_reg_t mspi_clk_conf;
volatile pcr_i2c0_conf_reg_t i2c0_conf;
volatile pcr_i2c0_sclk_conf_reg_t i2c0_sclk_conf;
volatile pcr_i2c1_conf_reg_t i2c1_conf;
volatile pcr_i2c1_sclk_conf_reg_t i2c1_sclk_conf;
volatile pcr_i2c_reg_t i2c[2];
volatile pcr_uhci_conf_reg_t uhci_conf;
volatile pcr_rmt_conf_reg_t rmt_conf;
volatile pcr_rmt_sclk_conf_reg_t rmt_sclk_conf;

View File

@ -49,6 +49,7 @@
#define SOC_RMT_SUPPORTED 1
// #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264
#define SOC_LEDC_SUPPORTED 1
#define SOC_I2C_SUPPORTED 1
#define SOC_SYSTIMER_SUPPORTED 1
// #define SOC_SUPPORT_COEXISTENCE 1 // TODO: IDF-6416
#define SOC_AES_SUPPORTED 1
@ -169,19 +170,18 @@
#define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */
#define SOC_DEDIC_PERIPH_ALWAYS_ENABLE (1) /*!< The dedicated GPIO (a.k.a. fast GPIO) is featured by some customized CPU instructions, which is always enabled */
// TODO: IDF-6233
/*-------------------------- I2C CAPS ----------------------------------------*/
// ESP32-C6 has 1 I2C
#define SOC_I2C_NUM (1U)
// ESP32-H2 has 2 I2C
#define SOC_I2C_NUM (2U)
#define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */
// #define SOC_I2C_SUPPORT_SLAVE (1)
#define SOC_I2C_SUPPORT_SLAVE (1)
// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined.
#define SOC_I2C_SUPPORT_HW_CLR_BUS (1)
#define SOC_I2C_SUPPORT_XTAL (1)
#define SOC_I2C_SUPPORT_RTC (1)
// #define SOC_I2C_SUPPORT_RTC (1) // TODO: IDF-6254
/*-------------------------- I2S CAPS ----------------------------------------*/
#define SOC_I2S_NUM (1U)

View File

@ -342,7 +342,7 @@ Customized Configuration
As mentioned at the end of Section :ref:`i2c-api-configure-driver`, when the function :cpp:func:`i2c_param_config` initializes the driver configuration for an I2C port, it also sets several I2C communication parameters to default values defined in the I2C specification. Some other related parameters are pre-configured in registers of the I2C controller.
All these parameters can be changed to user-defined values by calling dedicated functions given in the table below. Please note that the timing values are defined in APB clock cycles. The frequency of APB is specified in :c:macro:`I2C_APB_CLK_FREQ`.
All these parameters can be changed to user-defined values by calling dedicated functions given in the table below. Please note that the timing values are defined in APB clock cycles.
.. list-table:: Other Configurable I2C Communication Parameters
:widths: 65 35

View File

@ -342,7 +342,7 @@ I2C 驱动程序管理在 I2C 总线上设备的通信,该驱动程序具备
如本节末尾所述 :ref:`i2c-api-configure-driver`,函数 :cpp:func:`i2c_param_config` 在初始化 I2C 端口的驱动程序配置时,也会将几个 I2C 通信参数设置为 I2C 总线协议规范规定的默认值。其他一些相关参数已在 I2C 控制器的寄存器中预先配置。
通过调用下表中提供的专用函数,可以将所有这些参数更改为用户自定义值。请注意,时序值是在 APB 时钟周期中定义。APB 的频率在 :c:macro:`I2C_APB_CLK_FREQ` 中指定。
通过调用下表中提供的专用函数,可以将所有这些参数更改为用户自定义值。请注意,时序值是在 APB 时钟周期中定义。
.. list-table:: 其他可配置的 I2C 通信参数
:widths: 65 35

View File

@ -52,13 +52,13 @@ examples/peripherals/i2s/i2s_basic/i2s_tdm:
examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm:
disable:
- if: SOC_I2S_SUPPORTS_TDM != 1 or SOC_I2C_SUPPORTED != 1
reason: rely on I2S TDM mode and I2C support
- if: SOC_I2S_SUPPORTS_TDM != 1 or (SOC_I2C_SUPPORTED != 1 or SOC_GPSPI_SUPPORTED != 1)
reason: rely on I2S TDM mode to receive audio, I2C to config es7210 and SPI to save audio to SD card
examples/peripherals/i2s/i2s_codec/i2s_es8311:
disable:
- if: SOC_I2S_SUPPORTED != 1 or SOC_I2C_SUPPORTED != 1
reason: rely on I2S STD mode and I2C support
reason: rely on I2S STD mode and I2C to config es7210
examples/peripherals/i2s/i2s_recorder:
enable:
@ -66,7 +66,8 @@ examples/peripherals/i2s/i2s_recorder:
examples/peripherals/lcd/i2c_oled:
disable:
- if: SOC_I2C_SUPPORTED != 1
- if: SOC_I2C_SUPPORTED != 1 or IDF_TARGET == "esp32h2"
reason: LCD has not been supported on esp32h2, IDF-6213
examples/peripherals/lcd/i80_controller:
disable:

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# I2C Self-Test Example

View File

@ -7,7 +7,7 @@ menu "Example Configuration"
config I2C_MASTER_SCL
int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 2 if IDF_TARGET_ESP32S3
default 2 if IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32H2
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
default 6
help
@ -16,7 +16,7 @@ menu "Example Configuration"
config I2C_MASTER_SDA
int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 1 if IDF_TARGET_ESP32S3
default 1 if IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32H2
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
default 5
help
@ -24,7 +24,7 @@ menu "Example Configuration"
config I2C_MASTER_PORT_NUM
int "Port Number"
default 1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 1 if SOC_I2C_NUM > 1
default 0
help
Port number for I2C Master device.

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# I2C Simple Example

View File

@ -6,7 +6,7 @@ menu "Example Configuration"
int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 6
default 2
help
GPIO number for I2C Master clock line.
@ -14,7 +14,7 @@ menu "Example Configuration"
int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 5
default 1
help
GPIO number for I2C Master data line.

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# I2C Tools Example

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -28,7 +28,7 @@
static const char *TAG = "cmd_i2ctools";
#if CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
static gpio_num_t i2c_gpio_sda = 1;
static gpio_num_t i2c_gpio_scl = 2;
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# I2S ES8311 Example