diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/README.md b/components/esp_driver_i2c/test_apps/i2c_test_apps/README.md index 3a502b1f86..7b96141437 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/README.md +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_lcd/test_apps/i2c_lcd/README.md b/components/esp_lcd/test_apps/i2c_lcd/README.md index 4b3c3e235a..94fdad27b4 100644 --- a/components/esp_lcd/test_apps/i2c_lcd/README.md +++ b/components/esp_lcd/test_apps/i2c_lcd/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | This test app is used to test LCDs with I2C interface. diff --git a/components/esp_lcd/test_apps/i2c_lcd_legacy/README.md b/components/esp_lcd/test_apps/i2c_lcd_legacy/README.md index 4b3c3e235a..94fdad27b4 100644 --- a/components/esp_lcd/test_apps/i2c_lcd_legacy/README.md +++ b/components/esp_lcd/test_apps/i2c_lcd_legacy/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | This test app is used to test LCDs with I2C interface. diff --git a/components/hal/esp32c5/include/hal/i2c_ll.h b/components/hal/esp32c5/include/hal/i2c_ll.h index 0e46063988..c81f0103f3 100644 --- a/components/hal/esp32c5/include/hal/i2c_ll.h +++ b/components/hal/esp32c5/include/hal/i2c_ll.h @@ -12,7 +12,6 @@ #include "soc/soc_caps.h" #include "hal/misc.h" #include "hal/assert.h" -#if SOC_I2C_SUPPORTED // TODO: [ESP32C5] IDF-8694 #include "soc/i2c_periph.h" #include "soc/soc_caps.h" #include "soc/i2c_struct.h" @@ -1240,5 +1239,3 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l #ifdef __cplusplus } #endif - -#endif // SOC_I2C_SUPPORTED diff --git a/components/hal/esp32c61/include/hal/i2c_ll.h b/components/hal/esp32c61/include/hal/i2c_ll.h new file mode 100644 index 0000000000..9a671075ce --- /dev/null +++ b/components/hal/esp32c61/include/hal/i2c_ll.h @@ -0,0 +1,1167 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for I2C register operations + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "hal/misc.h" +#include "hal/assert.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" +#include "soc/lp_clkrst_struct.h" +#include "soc/lpperi_struct.h" +#include "hal/misc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2C hardware cmd register fields. + */ +typedef union { + struct { + uint32_t byte_num: 8, /*!< Specifies the length of data (in bytes) to be read or written */ + ack_en: 1, /*!< Used to enable the I2C controller during a write operation to check whether ACK */ + ack_exp: 1, /*!< Used to configure the level of the ACK bit expected by the I2C controller during a write operation */ + ack_val: 1, /*!< Used to configure the level of the ACK bit sent by the I2C controller during a read operation */ + op_code: 3, /*!< Indicates the command */ + reserved14: 17, /*!< Reserved bits */ + done: 1; /*!< Indicates that a command has been executed */ + }; + uint32_t val; +} i2c_ll_hw_cmd_t; + +// I2C operation mode command +#define I2C_LL_CMD_RESTART 6 /*!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->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; + + /* Verify the assumptions made by the hardware */ + HAL_ASSERT(clk_cal->scl_wait_high < clk_cal->sda_sample && + clk_cal->sda_sample < clk_cal->scl_high); +} + +/** + * @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 Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + HAL_ASSERT(i2c_port >= 0 && i2c_port < SOC_I2C_NUM); + PCR.i2c_conf.i2c_clk_en = enable; +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + HAL_ASSERT(i2c_port >= 0 && i2c_port < SOC_I2C_NUM); + PCR.i2c_conf.i2c_rst_en = 1; + PCR.i2c_conf.i2c_rst_en = 0; +} + +/** + * @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_master_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_num, bus_cfg->clkm_div - 1); + + /* 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 Set fractional divider + * + * @param hw Beginning address of the peripheral registers + * @param div_a The denominator of the frequency divider factor of the i2c function clock + * @param div_b The numerator of the frequency divider factor of the i2c function clock. + */ +static inline void i2c_ll_master_set_fractional_divider(i2c_dev_t *hw, uint8_t div_a, uint8_t div_b) +{ + /* Set div_a and div_b to 0, as it's not necessary to use them */ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_a, div_a); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_b, div_b); +} + +/** + * @brief Reset I2C txFIFO + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +__attribute__((always_inline)) +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 + */ +__attribute__((always_inline)) +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 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 + */ +__attribute__((always_inline)) +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_slave_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 broadcasting mode. + * + * @param hw Beginning address of the peripheral registers + * @param broadcast_en Set true to enable broadcast, else, set it false + * + * @return None + */ +static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_en) +{ + hw->ctr.addr_broadcasting_en = broadcast_en; +} + +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @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.addr_10bit_en = addr_10bit_en; + if (addr_10bit_en) { + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; + uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; + hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; + hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; + } else { + hw->slave_addr.slave_addr = slave_addr; + } +} + +/** + * @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 + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_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_master_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_master_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.fifo_prt_en = 1; + 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 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 + */ +__attribute__((always_inline)) +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 + */ +__attribute__((always_inline)) +static inline void i2c_ll_master_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 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 written + * + * @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 Write the I2C hardware txFIFO + * + * @param hw Beginning address of the peripheral registers + * @param ram_offset Offset value of I2C RAM. + * @param ptr Pointer to data buffer + * @param len Amount of data needs to be written + */ +static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) +{ + for (int i = 0; i < len; i++) { + hw->txfifo_mem[i + ram_offset] = ptr[i]; + } +} + +/** + * @brief Read the I2C hardware ram + * + * @param hw Beginning address of the peripheral registers + * @param ram_offset Offset value of I2C RAM. + * @param ptr Pointer to data buffer + * @param len Amount of data needs read + */ +static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) +{ + for (int i = 0; i < len; i++) { + ptr[i] = hw->rxfifo_mem[i + ram_offset]; + } +} + +/** + * @brief Get access to I2C RAM address directly + * + * @param hw Beginning address of the peripheral registers + * @param addr_wr_en Enable I2C ram address read and write + * + * @return None +*/ +static inline void i2c_ll_enable_mem_access_nonfifo(i2c_dev_t *hw, bool addr_wr_en) +{ + hw->fifo_conf.fifo_addr_cfg_en = addr_wr_en; +} + +/** + * @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_master_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_master_get_filter(i2c_dev_t *hw, uint8_t *filter_conf) +{ + *filter_conf = hw->filter_cfg.scl_filter_thres; +} + +/** + * @brief Reset 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 + * @param slave_pulses When I2C master is IDLE, the number of pulses will be sent out. + * + * @return None + */ +static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw, uint32_t slave_pulses) +{ + hw->scl_sp_conf.scl_rst_slv_num = slave_pulses; + hw->scl_sp_conf.scl_rst_slv_en = 1; + hw->ctr.conf_upgate = 1; + // hardware 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 the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value. + * ack_level: 1 (NACK) + * ack_level: 0 (ACK) + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level) +{ + hw->ctr.rx_full_ack_level = ack_level; +} + +/** + * @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 RC_FAST, (0) for XTAL + PCR.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) +{ + PCR.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; +} + +/** + * @brief Enable I2C slave clock stretch. + * + * @param dev Beginning address of the peripheral registers. + * @param enable true: Enable, false: Disable. + */ +static inline void i2c_ll_slave_enable_scl_stretch(i2c_dev_t *dev, bool enable) +{ + dev->scl_stretch_conf.slave_scl_stretch_en = enable; +} + +/** + * @brief Clear I2C clock stretch status + * + * @param dev Beginning address of the peripheral registers + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_clear_stretch(i2c_dev_t *dev) +{ + dev->scl_stretch_conf.slave_scl_stretch_clr = 1; +} + +/** + * @brief Check if i2c command is done. + * + * @param hw Beginning address of the peripheral registers + * @param cmd_idx The index of the command register, must be less than 8 + * + * @return True if the `cmd_idx` command is done. Otherwise false. + */ +__attribute__((always_inline)) +static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx) +{ + return hw->command[cmd_idx].command_done; +} + +/** + * @brief Calculate SCL timeout us to reg value + * + * @param timeout_us timeout value in us + * @param src_clk_hz source clock frequency + * @return uint32_t reg value + */ +static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us) +{ + uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000); + return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us); +} + +//////////////////////////////////////////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 height period (in core clock cycle, height_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; + int_sts.val = hw->int_status.val; + + 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; + int_sts.val = hw->int_status.val; + 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 + */ +__attribute__((always_inline)) +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 + */ +__attribute__((always_inline)) +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); +} + +/** + * @brief Configure I2C SCL timing + * + * @param hw Beginning address of the peripheral registers + * @param height_period The I2C SCL height period (in core clock cycle, height_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 height_period, int low_period) +{ + hw->scl_low_period.scl_low_period = low_period - 1; + hw->scl_high_period.scl_high_period = height_period - 10; + hw->scl_high_period.scl_wait_high_period = height_period - hw->scl_high_period.scl_high_period; +} + +/** + * @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 = (i2c_trans_mode_t)(hw->ctr.tx_lsb_first); + *rx_mode = (i2c_trans_mode_t)(hw->ctr.rx_lsb_first); +} + +/** + * @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; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/test_apps/hal_i2c/README.md b/components/hal/test_apps/hal_i2c/README.md index 2d5b6a950a..f72bb58061 100644 --- a/components/hal/test_apps/hal_i2c/README.md +++ b/components/hal/test_apps/hal_i2c/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | # HAL I2C test diff --git a/components/soc/esp32/i2c_periph.c b/components/soc/esp32/i2c_periph.c index deee5ceb5d..daecec7bee 100644 --- a/components/soc/esp32/i2c_periph.c +++ b/components/soc/esp32/i2c_periph.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/i2c_periph.h" #include "soc/gpio_sig_map.h" @@ -25,7 +17,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = I2CEXT1_SDA_OUT_IDX, @@ -33,6 +24,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT1_SCL_OUT_IDX, .scl_in_sig = I2CEXT1_SCL_IN_IDX, .irq = ETS_I2C_EXT1_INTR_SOURCE, - .module = PERIPH_I2C1_MODULE, }, }; diff --git a/components/soc/esp32c2/i2c_periph.c b/components/soc/esp32c2/i2c_periph.c index cb8e7fa246..0087252478 100644 --- a/components/soc/esp32c2/i2c_periph.c +++ b/components/soc/esp32c2/i2c_periph.c @@ -17,6 +17,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, }; diff --git a/components/soc/esp32c3/i2c_periph.c b/components/soc/esp32c3/i2c_periph.c index 67dfbc56e0..2402f6aeae 100644 --- a/components/soc/esp32c3/i2c_periph.c +++ b/components/soc/esp32c3/i2c_periph.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/i2c_periph.h" #include "soc/gpio_sig_map.h" @@ -25,6 +17,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, }; diff --git a/components/soc/esp32c5/i2c_periph.c b/components/soc/esp32c5/i2c_periph.c index 2ad3380e61..5cc53907f9 100644 --- a/components/soc/esp32c5/i2c_periph.c +++ b/components/soc/esp32c5/i2c_periph.c @@ -29,7 +29,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_in_sig = I2CEXT0_SCL_IN_IDX, .iomux_func = (uint8_t)LP_MUX_FUNC_NOT_USED, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, /* LP_I2C_NUM_0*/ { @@ -39,6 +38,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_in_sig = 0, .iomux_func = (uint8_t)LP_I2C_MUX_FUNC, .irq = ETS_LP_I2C_INTR_SOURCE, - .module = PERIPH_LP_I2C0_MODULE, }, }; diff --git a/components/soc/esp32c5/include/soc/clk_tree_defs.h b/components/soc/esp32c5/include/soc/clk_tree_defs.h index 375d118fe9..b1955e2225 100644 --- a/components/soc/esp32c5/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/include/soc/clk_tree_defs.h @@ -329,7 +329,7 @@ typedef enum { /** * @brief Type of I2C clock source. */ -typedef enum { // TODO: [ESP32C5] IDF-8694, IDF-8696 (inherit from C6) +typedef enum { 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 */ diff --git a/components/soc/esp32c6/i2c_periph.c b/components/soc/esp32c6/i2c_periph.c index 465a5dc5c6..2177144474 100644 --- a/components/soc/esp32c6/i2c_periph.c +++ b/components/soc/esp32c6/i2c_periph.c @@ -21,7 +21,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = 0, @@ -30,7 +29,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_in_sig = 0, .iomux_func = LP_I2C_MUX_FUNC, .irq = ETS_LP_I2C_INTR_SOURCE, - .module = PERIPH_LP_I2C0_MODULE, }, }; diff --git a/components/soc/esp32c61/i2c_periph.c b/components/soc/esp32c61/i2c_periph.c new file mode 100644 index 0000000000..cc11ee808f --- /dev/null +++ b/components/soc/esp32c61/i2c_periph.c @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/i2c_periph.h" +#include "soc/gpio_sig_map.h" + + +/* + Bunch of constants for every I2C peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { + /* I2C_NUM_0*/ + { + .sda_out_sig = I2CEXT0_SDA_OUT_IDX, + .sda_in_sig = I2CEXT0_SDA_IN_IDX, + .scl_out_sig = I2CEXT0_SCL_OUT_IDX, + .scl_in_sig = I2CEXT0_SCL_IN_IDX, + .irq = ETS_I2C_EXT0_INTR_SOURCE, + }, +}; diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 2390aa09bd..a4330f799a 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -51,6 +51,10 @@ config SOC_RTC_MEM_SUPPORTED bool default y +config SOC_I2C_SUPPORTED + bool + default y + config SOC_SYSTIMER_SUPPORTED bool default y @@ -263,6 +267,58 @@ config SOC_DEDIC_PERIPH_ALWAYS_ENABLE bool default y +config SOC_I2C_NUM + int + default 1 + +config SOC_HP_I2C_NUM + int + default 1 + +config SOC_I2C_FIFO_LEN + int + default 32 + +config SOC_I2C_CMD_REG_NUM + int + default 8 + +config SOC_I2C_SUPPORT_SLAVE + bool + default y + +config SOC_I2C_SUPPORT_HW_FSM_RST + bool + default y + +config SOC_I2C_SUPPORT_XTAL + bool + default y + +config SOC_I2C_SUPPORT_RTC + bool + default y + +config SOC_I2C_SUPPORT_10BIT_ADDR + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK bool default y diff --git a/components/soc/esp32c61/include/soc/i2c_struct.h b/components/soc/esp32c61/include/soc/i2c_struct.h index 5c16c1e6e5..4cb22ab31c 100644 --- a/components/soc/esp32c61/include/soc/i2c_struct.h +++ b/components/soc/esp32c61/include/soc/i2c_struct.h @@ -1040,34 +1040,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1091,7 +1063,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_comd_reg_t comd[8]; + 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; @@ -1099,15 +1071,14 @@ typedef struct { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; -extern i2c_dev_t I2C; +extern i2c_dev_t I2C0; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 3766b6c5e5..0c52fe816f 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -38,7 +38,7 @@ // \#define SOC_I2S_SUPPORTED 1 //TODO: [ESP32C61] IDF-9312, IDF-9313 // \#define SOC_GPSPI_SUPPORTED 1 //TODO: [ESP32C61] IDF-9299, IDF-9300, IDF-9301 // \#define SOC_LEDC_SUPPORTED 1 //TODO: [ESP32C61] IDF-9291 -// \#define SOC_I2C_SUPPORTED 1 //TODO: [ESP32C61] IDF-9296, IDF-9297 +#define SOC_I2C_SUPPORTED 1 #define SOC_SYSTIMER_SUPPORTED 1 //TODO: [ESP32C61] IDF-9307, IDF-9308 // \#define SOC_SUPPORT_COEXISTENCE 1 // \#define SOC_SHA_SUPPORTED 1 //TODO: [ESP32C61] IDF-9234 @@ -210,29 +210,21 @@ /*-------------------------- I2C CAPS ----------------------------------------*/ // ESP32-C61 has 1 I2C -// #define SOC_I2C_NUM (1U) -// #define SOC_HP_I2C_NUM (1U) +#define SOC_I2C_NUM (1U) +#define SOC_HP_I2C_NUM (1U) -// #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ -// #define SOC_I2C_CMD_REG_NUM (8) /*!< Number of I2C command registers */ -// #define SOC_I2C_SUPPORT_SLAVE (1) +#define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_CMD_REG_NUM (8) /*!< Number of I2C command registers */ +#define SOC_I2C_SUPPORT_SLAVE (1) -// #define SOC_I2C_SUPPORT_HW_FSM_RST (1) -// #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) - -// #define SOC_I2C_SUPPORT_XTAL (1) -// #define SOC_I2C_SUPPORT_RTC (1) -// #define SOC_I2C_SUPPORT_10BIT_ADDR (1) -// #define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) -// #define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) -// #define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) -// #define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) - -/*-------------------------- LP_I2C CAPS -------------------------------------*/ -// ESP32-C61 has 1 LP_I2C -// #define SOC_LP_I2C_NUM (1U) - -// #define SOC_LP_I2C_FIFO_LEN (16) /*!< LP_I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +#define SOC_I2C_SUPPORT_XTAL (1) +#define SOC_I2C_SUPPORT_RTC (1) +#define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) // /*-------------------------- I2S CAPS ----------------------------------------*/ // #define SOC_I2S_NUM (1U) diff --git a/components/soc/esp32c61/ld/esp32c61.peripherals.ld b/components/soc/esp32c61/ld/esp32c61.peripherals.ld index 289c95dd0e..b02ddc9703 100644 --- a/components/soc/esp32c61/ld/esp32c61.peripherals.ld +++ b/components/soc/esp32c61/ld/esp32c61.peripherals.ld @@ -8,7 +8,7 @@ PROVIDE ( UART0 = 0x60000000 ); PROVIDE ( UART1 = 0x60001000 ); PROVIDE ( SPIMEM0 = 0x60002000 ); PROVIDE ( SPIMEM1 = 0x60003000 ); -PROVIDE ( I2C = 0x60004000 ); +PROVIDE ( I2C0 = 0x60004000 ); PROVIDE ( UART2 = 0x60006000 ); PROVIDE ( LEDC = 0x60007000 ); PROVIDE ( TIMERG0 = 0x60008000 ); diff --git a/components/soc/esp32h2/i2c_periph.c b/components/soc/esp32h2/i2c_periph.c index a75f670e52..f1fd089056 100644 --- a/components/soc/esp32h2/i2c_periph.c +++ b/components/soc/esp32h2/i2c_periph.c @@ -19,7 +19,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = I2CEXT1_SDA_OUT_IDX, @@ -27,7 +26,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT1_SCL_OUT_IDX, .scl_in_sig = I2CEXT1_SCL_IN_IDX, .irq = ETS_I2C_EXT1_INTR_SOURCE, - .module = PERIPH_I2C1_MODULE, }, }; diff --git a/components/soc/esp32p4/i2c_periph.c b/components/soc/esp32p4/i2c_periph.c index ec79b087da..41c208dda0 100644 --- a/components/soc/esp32p4/i2c_periph.c +++ b/components/soc/esp32p4/i2c_periph.c @@ -18,7 +18,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2C0_SCL_PAD_OUT_IDX, .scl_in_sig = I2C0_SCL_PAD_IN_IDX, .irq = ETS_I2C0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = I2C1_SDA_PAD_OUT_IDX, @@ -26,7 +25,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2C1_SCL_PAD_OUT_IDX, .scl_in_sig = I2C1_SCL_PAD_IN_IDX, .irq = ETS_I2C1_INTR_SOURCE, - .module = PERIPH_I2C1_MODULE, }, { .sda_out_sig = LP_I2C_SDA_PAD_OUT_IDX, @@ -34,6 +32,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = LP_I2C_SCL_PAD_OUT_IDX, .scl_in_sig = LP_I2C_SCL_PAD_IN_IDX, .irq = ETS_LP_I2C_INTR_SOURCE, - .module = PERIPH_LP_I2C0_MODULE, }, }; diff --git a/components/soc/esp32s2/i2c_periph.c b/components/soc/esp32s2/i2c_periph.c index deee5ceb5d..daecec7bee 100644 --- a/components/soc/esp32s2/i2c_periph.c +++ b/components/soc/esp32s2/i2c_periph.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/i2c_periph.h" #include "soc/gpio_sig_map.h" @@ -25,7 +17,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = I2CEXT1_SDA_OUT_IDX, @@ -33,6 +24,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT1_SCL_OUT_IDX, .scl_in_sig = I2CEXT1_SCL_IN_IDX, .irq = ETS_I2C_EXT1_INTR_SOURCE, - .module = PERIPH_I2C1_MODULE, }, }; diff --git a/components/soc/esp32s3/i2c_periph.c b/components/soc/esp32s3/i2c_periph.c index 32065ef7b7..daecec7bee 100644 --- a/components/soc/esp32s3/i2c_periph.c +++ b/components/soc/esp32s3/i2c_periph.c @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/i2c_periph.h" #include "soc/gpio_sig_map.h" @@ -25,7 +17,6 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT0_SCL_OUT_IDX, .scl_in_sig = I2CEXT0_SCL_IN_IDX, .irq = ETS_I2C_EXT0_INTR_SOURCE, - .module = PERIPH_I2C0_MODULE, }, { .sda_out_sig = I2CEXT1_SDA_OUT_IDX, @@ -33,6 +24,5 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { .scl_out_sig = I2CEXT1_SCL_OUT_IDX, .scl_in_sig = I2CEXT1_SCL_IN_IDX, .irq = ETS_I2C_EXT1_INTR_SOURCE, - .module = PERIPH_I2C1_MODULE, }, }; diff --git a/components/soc/include/soc/i2c_periph.h b/components/soc/include/soc/i2c_periph.h index c72e7720f1..408da3afc4 100644 --- a/components/soc/include/soc/i2c_periph.h +++ b/components/soc/include/soc/i2c_periph.h @@ -8,16 +8,14 @@ #include "soc/i2c_reg.h" #include "soc/i2c_struct.h" #include "soc/soc_caps.h" -#if SOC_I2C_SUPPORTED // TODO: [ESP32C5] IDF-8694 -#include "soc/periph_defs.h" +#if SOC_I2C_SUPPORTED #include "soc/regdma.h" -#endif // SOC_I2C_SUPPORTED +#include "soc/interrupts.h" #ifdef __cplusplus extern "C" { #endif -#if SOC_I2C_SUPPORTED typedef struct { const uint8_t sda_out_sig; const uint8_t sda_in_sig; @@ -25,7 +23,6 @@ typedef struct { const uint8_t scl_in_sig; const uint8_t iomux_func; const uint8_t irq; - const periph_module_t module; } i2c_signal_conn_t; extern const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM]; @@ -38,8 +35,8 @@ typedef struct { extern const i2c_reg_ctx_link_t i2c_regs_retention[SOC_HP_I2C_NUM]; #endif -#endif // SOC_I2C_SUPPORTED #ifdef __cplusplus } #endif +#endif // SOC_I2C_SUPPORTED diff --git a/docs/docs_not_updated/esp32c61.txt b/docs/docs_not_updated/esp32c61.txt index 9f71b83a24..d9a11a9ebb 100644 --- a/docs/docs_not_updated/esp32c61.txt +++ b/docs/docs_not_updated/esp32c61.txt @@ -109,7 +109,6 @@ api-reference/peripherals/spi_flash/index.rst api-reference/peripherals/touch_pad.rst api-reference/peripherals/lcd/i80_lcd.rst api-reference/peripherals/lcd/spi_lcd.rst -api-reference/peripherals/lcd/i2c_lcd.rst api-reference/peripherals/lcd/dsi_lcd.rst api-reference/peripherals/lcd/index.rst api-reference/peripherals/lcd/rgb_lcd.rst @@ -117,7 +116,6 @@ api-reference/peripherals/adc_calibration.rst api-reference/peripherals/spi_slave_hd.rst api-reference/peripherals/parlio.rst api-reference/peripherals/ds.rst -api-reference/peripherals/i2c.rst api-reference/peripherals/sd_pullup_requirements.rst api-reference/peripherals/spi_master.rst api-reference/peripherals/index.rst diff --git a/examples/peripherals/i2c/i2c_eeprom/README.md b/examples/peripherals/i2c/i2c_eeprom/README.md index 6132f3446c..dd873b1b2e 100644 --- a/examples/peripherals/i2c/i2c_eeprom/README.md +++ b/examples/peripherals/i2c/i2c_eeprom/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | # I2C EEPROM example diff --git a/examples/peripherals/i2c/i2c_tools/README.md b/examples/peripherals/i2c/i2c_tools/README.md index d72d84901f..400b6f041c 100644 --- a/examples/peripherals/i2c/i2c_tools/README.md +++ b/examples/peripherals/i2c/i2c_tools/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | # I2C Tools Example diff --git a/examples/peripherals/lcd/i2c_oled/README.md b/examples/peripherals/lcd/i2c_oled/README.md index d2e9d346b7..e2aa08466c 100644 --- a/examples/peripherals/lcd/i2c_oled/README.md +++ b/examples/peripherals/lcd/i2c_oled/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | # I2C OLED example diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b6542bc3e1..085339642f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -514,7 +514,6 @@ components/sdmmc/sdmmc_io.c components/sdmmc/sdmmc_mmc.c components/sdmmc/sdmmc_sd.c components/soc/esp32/adc_periph.c -components/soc/esp32/i2c_periph.c components/soc/esp32/include/soc/bb_reg.h components/soc/esp32/include/soc/boot_mode.h components/soc/esp32/include/soc/fe_reg.h @@ -558,7 +557,6 @@ components/soc/esp32/include/soc/uhci_struct.h components/soc/esp32/include/soc/wdev_reg.h components/soc/esp32/ledc_periph.c components/soc/esp32/spi_periph.c -components/soc/esp32c3/i2c_periph.c components/soc/esp32c3/include/soc/apb_saradc_reg.h components/soc/esp32c3/include/soc/assist_debug_reg.h components/soc/esp32c3/include/soc/bb_reg.h @@ -589,7 +587,6 @@ components/soc/esp32c3/include/soc/wdev_reg.h components/soc/esp32c3/interrupts.c components/soc/esp32c3/ledc_periph.c components/soc/esp32s2/adc_periph.c -components/soc/esp32s2/i2c_periph.c components/soc/esp32s2/include/soc/apb_saradc_reg.h components/soc/esp32s2/include/soc/assist_debug_reg.h components/soc/esp32s2/include/soc/bb_reg.h @@ -624,7 +621,6 @@ components/soc/esp32s2/include/soc/usb_wrap_reg.h components/soc/esp32s2/include/soc/usb_wrap_struct.h components/soc/esp32s2/include/soc/wdev_reg.h components/soc/esp32s2/ledc_periph.c -components/soc/esp32s3/i2c_periph.c components/soc/esp32s3/include/soc/apb_saradc_reg.h components/soc/esp32s3/include/soc/assist_debug_reg.h components/soc/esp32s3/include/soc/assist_debug_struct.h