diff --git a/components/driver/test_apps/legacy_i2c_driver/README.md b/components/driver/test_apps/legacy_i2c_driver/README.md index 44f3780f1d..d76348d52c 100644 --- a/components/driver/test_apps/legacy_i2c_driver/README.md +++ b/components/driver/test_apps/legacy_i2c_driver/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | 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 44f3780f1d..d76348d52c 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-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.cpp b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.cpp index 9c559a4393..f54f11180b 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.cpp +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.cpp @@ -306,7 +306,7 @@ TEST_CASE("I2C master transaction non-blocking mode with large amount of transac i2c_device_config_t dev_cfg = {}; dev_cfg.dev_addr_length = I2C_ADDR_BIT_LEN_7; dev_cfg.device_address = 0x58; - dev_cfg.scl_speed_hz = 400000; + dev_cfg.scl_speed_hz = 200000; dev_cfg.flags.disable_ack_check = true; i2c_master_dev_handle_t dev_handle; diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.cpp b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.cpp index 18bd89ef9f..7f357718ff 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.cpp +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -80,6 +80,8 @@ TEST_CASE("LP I2C initialize with wrong IO", "[i2c]") #endif +#if !CONFIG_IDF_TARGET_ESP32S31 // LP_I2C has the same clock source as HP_I2C on ESP32S31 + TEST_CASE("LP I2C initialize with wrong clock source", "[i2c]") { i2c_master_bus_config_t i2c_mst_config = {}; @@ -94,6 +96,8 @@ TEST_CASE("LP I2C initialize with wrong clock source", "[i2c]") TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_new_master_bus(&i2c_mst_config, &bus_handle)); } +#endif + static void lp_i2c_master_write_test(void) { uint8_t data_wr[DATA_LENGTH] = { 0 }; diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py index e59f9eadc7..5debc148b1 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py @@ -16,7 +16,6 @@ from pytest_embedded_idf.utils import soc_filtered_targets indirect=True, ) @idf_parametrize('target', ['supported_targets'], indirect=['target']) -@pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='s31 bringup on this module is not done') def test_i2c(dut: Dut) -> None: dut.run_all_single_board_cases() @@ -32,6 +31,7 @@ def test_i2c(dut: Dut) -> None: indirect=True, ) @idf_parametrize('target', soc_filtered_targets('SOC_I2C_SUPPORTED == 1'), indirect=['target']) +@pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='lack of s31 multi-device runner # TODO: IDFCI-10334') def test_i2c_multi_device(case_tester) -> None: # type: ignore case_tester.run_all_multi_dev_cases(reset=True) diff --git a/components/esp_hal_i2c/esp32c5/i2c_periph.c b/components/esp_hal_i2c/esp32c5/i2c_periph.c index c2d5a00a82..22617a96be 100644 --- a/components/esp_hal_i2c/esp32c5/i2c_periph.c +++ b/components/esp_hal_i2c/esp32c5/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,11 +40,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32c6/i2c_periph.c b/components/esp_hal_i2c/esp32c6/i2c_periph.c index a51c5b821c..28240575df 100644 --- a/components/esp_hal_i2c/esp32c6/i2c_periph.c +++ b/components/esp_hal_i2c/esp32c6/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,11 +41,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32c61/i2c_periph.c b/components/esp_hal_i2c/esp32c61/i2c_periph.c index 951b665d03..5509ee5493 100644 --- a/components/esp_hal_i2c/esp32c61/i2c_periph.c +++ b/components/esp_hal_i2c/esp32c61/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,11 +29,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32h2/i2c_periph.c b/components/esp_hal_i2c/esp32h2/i2c_periph.c index b39d28e18b..f7bceb5379 100644 --- a/components/esp_hal_i2c/esp32h2/i2c_periph.c +++ b/components/esp_hal_i2c/esp32h2/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,11 +38,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ @@ -66,9 +66,9 @@ static const regdma_entries_config_t i2c0_regs_retention[] = { }, \ }; -#define I2C1_RETENTION_REGS_CNT 18 +#define I2C1_RETENTION_REGS_CNT 17 #define I2C1_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(1) -static const uint32_t i2c1_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c1_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c1_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_REGS_CNT, 0, 0, i2c1_regs_map[0], i2c1_regs_map[1], i2c1_regs_map[2], i2c1_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32h4/i2c_periph.c b/components/esp_hal_i2c/esp32h4/i2c_periph.c index 73f672d978..6a667931da 100644 --- a/components/esp_hal_i2c/esp32h4/i2c_periph.c +++ b/components/esp_hal_i2c/esp32h4/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,11 +38,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG /I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ @@ -66,9 +66,9 @@ static const regdma_entries_config_t i2c0_regs_retention[] = { }, \ }; -#define I2C1_RETENTION_REGS_CNT 18 +#define I2C1_RETENTION_REGS_CNT 17 #define I2C1_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(1) -static const uint32_t i2c1_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c1_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c1_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_REGS_CNT, 0, 0, i2c1_regs_map[0], i2c1_regs_map[1], i2c1_regs_map[2], i2c1_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32p4/i2c_periph.c b/components/esp_hal_i2c/esp32p4/i2c_periph.c index e4365e6b41..1b7eed953f 100644 --- a/components/esp_hal_i2c/esp32p4/i2c_periph.c +++ b/components/esp_hal_i2c/esp32p4/i2c_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,11 +45,11 @@ const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = { Include: I2C_SCL_LOW_PERIOD_REG / I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG - I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_CLK_CONF_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG /I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG */ -#define I2C0_RETENTION_REGS_CNT 18 +#define I2C0_RETENTION_REGS_CNT 17 #define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) -static const uint32_t i2c0_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c0_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ @@ -73,9 +73,9 @@ static const regdma_entries_config_t i2c0_regs_retention[] = { }, \ }; -#define I2C1_RETENTION_REGS_CNT 18 +#define I2C1_RETENTION_REGS_CNT 17 #define I2C1_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(1) -static const uint32_t i2c1_regs_map[4] = {0xc03f345b, 0x3, 0, 0}; +static const uint32_t i2c1_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; static const regdma_entries_config_t i2c1_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_REGS_CNT, 0, 0, i2c1_regs_map[0], i2c1_regs_map[1], i2c1_regs_map[2], i2c1_regs_map[3]), \ diff --git a/components/esp_hal_i2c/esp32s31/i2c_periph.c b/components/esp_hal_i2c/esp32s31/i2c_periph.c new file mode 100644 index 0000000000..2e8424463f --- /dev/null +++ b/components/esp_hal_i2c/esp32s31/i2c_periph.c @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/i2c_periph.h" +#include "soc/gpio_sig_map.h" +#include "soc/lp_gpio_sig_map.h" +#include "soc/regdma.h" +#include "soc/i2c_reg.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] = { + { + .module_name = "I2C0", + .sda_out_sig = I2C0_SDA_PAD_OUT_IDX, + .sda_in_sig = I2C0_SDA_PAD_IN_IDX, + .scl_out_sig = I2C0_SCL_PAD_OUT_IDX, + .scl_in_sig = I2C0_SCL_PAD_IN_IDX, + .irq = ETS_I2C0_INTR_SOURCE, + }, + { + .module_name = "I2C1", + .sda_out_sig = I2C1_SDA_PAD_OUT_IDX, + .sda_in_sig = I2C1_SDA_PAD_IN_IDX, + .scl_out_sig = I2C1_SCL_PAD_OUT_IDX, + .scl_in_sig = I2C1_SCL_PAD_IN_IDX, + .irq = ETS_I2C1_INTR_SOURCE, + }, + { + .module_name = "LP_I2C0", + .sda_out_sig = LP_I2C_SDA_PAD_OUT_IDX, + .sda_in_sig = LP_I2C_SDA_PAD_IN_IDX, + .scl_out_sig = LP_I2C_SCL_PAD_OUT_IDX, + .scl_in_sig = LP_I2C_SCL_PAD_IN_IDX, + .irq = ETS_LP_I2C_INTR_SOURCE, + }, +}; + +// I2C sleep retention entries +// I2C registers require set the reg_update bit to make the configuration take effect + +/* I2C Registers Context + Include: I2C_SCL_LOW_PERIOD_REG / + I2C_CTR_REG / I2C_TO_REG / I2C_SLAVE_ADDR_REG / I2C_FIFO_CONF_REG + I2C_INT_ENA_REG / I2C_SDA_HOLD_REG / I2C_SDA_SAMPLE_REG / I2C_SCL_START_HOLD_REG + I2C_SCL_RSTART_SETUP_REG / I2C_SCL_STOP_HOLD_REG / I2C_SCL_STOP_SETUP_REG /I2C_FILTER_CFG_REG / I2C_SCL_ST_TIME_OUT_REG / I2C_SCL_MAIN_ST_TIME_OUT_REG / I2C_SCL_SP_CONF_REG / I2C_SCL_STRETCH_CONF_REG +*/ +#define I2C0_RETENTION_REGS_CNT 17 +#define I2C0_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(0) +static const uint32_t i2c0_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; +static const regdma_entries_config_t i2c0_regs_retention[] = { + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_MAP_BASE, I2C0_RETENTION_REGS_CNT, 0, 0, i2c0_regs_map[0], i2c0_regs_map[1], i2c0_regs_map[2], i2c0_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [1] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x01), I2C_CTR_REG(0), I2C_FSM_RST, I2C_FSM_RST_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [2] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x02), I2C_CTR_REG(0), 0x0, I2C_FSM_RST_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x03), I2C_CTR_REG(0), I2C_CONF_UPGATE, I2C_CONF_UPGATE_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [4] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_I2C_LINK(0x04), I2C_CTR_REG(0), 0x0, I2C_CONF_UPGATE_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ +}; + +#define I2C1_RETENTION_REGS_CNT 17 +#define I2C1_RETENTION_MAP_BASE I2C_SCL_LOW_PERIOD_REG(1) +static const uint32_t i2c1_regs_map[4] = {0xc01f345b, 0x3, 0, 0}; +static const regdma_entries_config_t i2c1_regs_retention[] = { + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_I2C_LINK(0x00), I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_MAP_BASE, I2C1_RETENTION_REGS_CNT, 0, 0, i2c1_regs_map[0], i2c1_regs_map[1], i2c1_regs_map[2], i2c1_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [1] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x01), I2C_CTR_REG(1), I2C_FSM_RST, I2C_FSM_RST_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [2] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x02), I2C_CTR_REG(1), 0x0, I2C_FSM_RST_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_I2C_LINK(0x03), I2C_CTR_REG(1), I2C_CONF_UPGATE, I2C_CONF_UPGATE_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ + [4] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_I2C_LINK(0x04), I2C_CTR_REG(1), 0x0, I2C_CONF_UPGATE_M, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ +}; + +const i2c_reg_ctx_link_t i2c_regs_retention[SOC_HP_I2C_NUM] = { + {i2c0_regs_retention, ARRAY_SIZE(i2c0_regs_retention), SLEEP_RETENTION_MODULE_I2C0}, + {i2c1_regs_retention, ARRAY_SIZE(i2c1_regs_retention), SLEEP_RETENTION_MODULE_I2C1}, +}; diff --git a/components/esp_hal_i2c/esp32s31/include/hal/i2c_ll.h b/components/esp_hal_i2c/esp32s31/include/hal/i2c_ll.h new file mode 100644 index 0000000000..e0b0e4f795 --- /dev/null +++ b/components/esp_hal_i2c/esp32s31/include/hal/i2c_ll.h @@ -0,0 +1,1313 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for I2C register operations + +#pragma once + +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/i2c_periph.h" +#include "soc/soc_caps.h" +#include "soc/i2c_struct.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/lp_peri_clkrst_struct.h" +#include "hal/i2c_types.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2C_LL_GET(_attr) I2C_LL_ ## _attr + +#define I2C_LL_FIFO_LEN 32 /*!< I2C hardware FIFO depth */ +#define I2C_LL_LP_FIFO_LEN 16 /*!< LP_I2C hardware FIFO depth */ +#define I2C_LL_CMD_REG_NUM 8 /*!< Number of I2C command registers */ + +#define I2C_LL_SUPPORT_HW_FSM_RST (1) /*!< Support hardware FSM reset */ +#define I2C_LL_SUPPORT_HW_CLR_BUS (1) /*!< Support hardware clear bus */ +// #define I2C_LL_SLAVE_SUPPORT_I2CRAM_ACCESS (1) /*!< Slave support I2CRAM access */ +// #define I2C_LL_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*!< Slave support slave unmatch */ + +/** + * @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) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.i2c0_ctrl0.reg_i2c0_apb_clk_en = enable; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.i2c1_ctrl0.reg_i2c1_apb_clk_en = enable; + } else { + HAL_ASSERT(false); + } +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.i2c0_ctrl0.reg_i2c0_rst_en = 1; + HP_SYS_CLKRST.i2c0_ctrl0.reg_i2c0_rst_en = 0; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.i2c1_ctrl0.reg_i2c1_rst_en = 1; + HP_SYS_CLKRST.i2c1_ctrl0.reg_i2c1_rst_en = 0; + } else { + HAL_ASSERT(false); + } +} + +/** + * @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) +{ + if (hw == &I2C0) { + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c0_ctrl0, reg_i2c0_clk_div_num, bus_cfg->clkm_div - 1); + } else if (hw == &I2C1) { + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c1_ctrl0, reg_i2c1_clk_div_num, bus_cfg->clkm_div - 1); + } else if (hw == &LP_I2C) { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_PERI_CLKRST.i2c_ctrl, lp_i2c_clk_div_num, bus_cfg->clkm_div - 1); + } else { + HAL_ASSERT(false); + } + + /* 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 */ + + if (hw == &I2C0) { + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c0_ctrl0, reg_i2c0_clk_div_numerator, div_a); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c0_ctrl0, reg_i2c0_clk_div_denominator, div_b); + } else if (hw == &I2C1) { + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c1_ctrl0, reg_i2c1_clk_div_numerator, div_a); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.i2c1_ctrl0, reg_i2c1_clk_div_denominator, div_b); + } else if (hw == &LP_I2C) { + // LP I2C does not have a fractional divider via LP_PERI_CLKRST + (void)div_a; + (void)div_b; + } else { + HAL_ASSERT(false); + } +} + +/** + * @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_enable_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 Enable the I2C slave to respond to broadcast address + * + * @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.fifo_prt_en = 1; + 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->ctr.rx_full_ack_level = 0; + 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 = (hw->sr.txfifo_cnt >= I2C_LL_GET(FIFO_LEN)) ? 0 : (I2C_LL_GET(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_start_trans(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++) { + hw->data.val = 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 to the TX RAM by direct address + * + * @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_tx_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 from the RX RAM by direct address + * + * @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_rx_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 Enable I2C slave dual addressing mode + * + * @note When enable the dual addressing mode, I2C RAM must be accessed in non-FIFO mode + * + * @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_slave_enable_dual_addressing_mode(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. + * @param enable True to start the state machine, otherwise, false + * + * @return None + */ +static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw, uint32_t slave_pulses, bool enable) +{ + hw->scl_sp_conf.scl_rst_slv_num = slave_pulses; + hw->scl_sp_conf.scl_rst_slv_en = enable; + 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 after this function. +} + +/** + * @brief Get the clear bus state + * + * @param hw Beginning address of the peripheral registers + * + * @return true: the clear bus not finish, otherwise, false. + */ +static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw) +{ + return hw->scl_sp_conf.scl_rst_slv_en; +} + +/** + * @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 + if (hw == &I2C0) { + HP_SYS_CLKRST.i2c0_ctrl0.reg_i2c0_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; + } else if (hw == &I2C1) { + HP_SYS_CLKRST.i2c1_ctrl0.reg_i2c1_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; + } else if (hw == &LP_I2C) { + // LP I2C source clock is configured via lp_i2c_ll_set_source_clk + return; + } else { + HAL_ASSERT(false); + } +} + +/** + * @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) +{ + if (hw == &I2C0) { + HP_SYS_CLKRST.i2c0_ctrl0.reg_i2c0_clk_en = en; + } else if (hw == &I2C1) { + HP_SYS_CLKRST.i2c1_ctrl0.reg_i2c1_clk_en = en; + } else if (hw == &LP_I2C) { + // LP I2C controller clock is managed via lp_i2c_ll_enable_bus_clock + return; + } else { + HAL_ASSERT(false); + } +} + +/** + * @brief Set the I2C bus mode (Master or Slave) + * + * @param hw Pointer to the I2C hardware register structure. + * @param mode The desired I2C bus mode (Master or Slave). + */ +static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode) +{ + hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0; +} + +/** + * @brief Enable or disable open-drain mode for I2C pins + * + * @param hw Pointer to the I2C hardware register structure. + * @param enable_od Boolean flag to enable or disable open-drain mode: + */ +static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od) +{ + hw->ctr.sda_force_out = !enable_od; + hw->ctr.scl_force_out = !enable_od; +} + +/** + * @brief Enable or disable arbitration for I2C communication. + * + * @param hw Pointer to the I2C hardware instance. + * @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration. + */ +static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi) +{ + hw->ctr.arbitration_en = enable_arbi; +} + +/** + * @brief Enable I2C slave to automatically send data when addressed by the 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_enable_auto_start(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 Set I2C clock stretch protect num + * + * @param dev Beginning address of the peripheral registers + */ +static inline void i2c_ll_slave_set_stretch_protect_num(i2c_dev_t *dev, uint32_t protect_num) +{ + dev->scl_stretch_conf.stretch_protect_num = protect_num; +} + +/** + * @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); + // round up to an integer + return 32 - __builtin_clz(clk_cycle_num_per_us * timeout_us); +} + +/** + * @brief Get status of i2c slave + * + * @param Beginning address of the peripheral registers + * @return i2c slave working status + */ +__attribute__((always_inline)) +static inline i2c_slave_read_write_status_t i2c_ll_slave_get_read_write_status(i2c_dev_t *hw) +{ + return (hw->sr.slave_rw == 0) ? I2C_SLAVE_WRITE_BY_MASTER : I2C_SLAVE_READ_BY_MASTER; +} + +/** + * @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, 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; +} + +//////////////////////////////////////////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 +// I2C max timeout period in clock cycles +#define I2C_LL_MAX_TIMEOUT_PERIOD (1UL << I2C_LL_MAX_TIMEOUT) + +#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 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 Enable I2C slave TX interrupt + * + * @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 hight_period The I2C SCL height 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 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; +} + +/** + * @brief Set LP I2C source clock + * + * @param hw Address offset of the LP I2C peripheral registers + * @param src_clk Source clock for the LP I2C peripheral + */ +static inline void lp_i2c_ll_set_source_clk(i2c_dev_t *hw, soc_periph_lp_i2c_clk_src_t src_clk) +{ + (void)hw; + // src_clk: (0) for LP_FAST_CLK (RTC Fast), (1) for XTAL_D2_CLK + switch (src_clk) { + case LP_I2C_SCLK_LP_FAST: + LP_PERI_CLKRST.i2c_ctrl.lp_i2c_clk_sel = 0; + break; + case LP_I2C_SCLK_XTAL: + LP_PERI_CLKRST.i2c_ctrl.lp_i2c_clk_sel = 1; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Enable bus clock for the LP I2C module + * + * @param hw_id LP I2C instance ID + * @param enable True to enable, False to disable + */ +static inline void lp_i2c_ll_enable_bus_clock(int hw_id, bool enable) +{ + (void)hw_id; + LP_PERI_CLKRST.i2c_ctrl.lp_i2c_clk_en = enable ? 1 : 0; +} + +/** + * @brief Reset LP I2C module + * + * @param hw_id LP I2C instance ID + */ +static inline void lp_i2c_ll_reset_register(int hw_id) +{ + (void)hw_id; + LP_PERI_CLKRST.i2c_ctrl.lp_i2c_rst_en = 1; + LP_PERI_CLKRST.i2c_ctrl.lp_i2c_rst_en = 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_i2c/test_apps/hal_i2c/README.md b/components/esp_hal_i2c/test_apps/hal_i2c/README.md index 7d3af1817d..9ddab91125 100644 --- a/components/esp_hal_i2c/test_apps/hal_i2c/README.md +++ b/components/esp_hal_i2c/test_apps/hal_i2c/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # HAL I2C test diff --git a/components/esp_lcd/test_apps/i2c_lcd/README.md b/components/esp_lcd/test_apps/i2c_lcd/README.md index 434a3d2264..39278eef4b 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-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | This test app is used to test LCDs with I2C interface. diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index b07cbe31f3..551b6424e6 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -83,6 +83,10 @@ config SOC_LEDC_SUPPORTED bool default y +config SOC_I2C_SUPPORTED + bool + default y + config SOC_SYSTIMER_SUPPORTED bool default y @@ -107,6 +111,10 @@ config SOC_LP_PERIPHERALS_SUPPORTED bool default y +config SOC_LP_I2C_SUPPORTED + bool + default y + config SOC_SPIRAM_SUPPORTED bool default y @@ -431,6 +439,46 @@ config SOC_RMT_SUPPORT_SLEEP_RETENTION bool default y +config SOC_I2C_NUM + int + default 3 + +config SOC_HP_I2C_NUM + int + default 2 + +config SOC_LP_I2C_NUM + int + default 1 + +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_SUPPORT_SLAVE + 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_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_MMU_PERIPH_NUM int default 2 diff --git a/components/soc/esp32s31/include/soc/clk_tree_defs.h b/components/soc/esp32s31/include/soc/clk_tree_defs.h index b557e83b31..bcc96a8f9f 100644 --- a/components/soc/esp32s31/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s31/include/soc/clk_tree_defs.h @@ -259,6 +259,38 @@ typedef enum { LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ } soc_periph_ledc_clk_src_legacy_t; +/////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of I2C + */ +#define SOC_I2C_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief Type of I2C clock source. + */ +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 clock choice */ +} soc_periph_i2c_clk_src_t; + +///////////////////////////////////////////////LP_I2C/////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of LP_I2C + */ +#define SOC_LP_I2C_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL} + +/** + * @brief Type of LP_I2C clock source. + */ +typedef enum { + LP_I2C_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock is RTC_FAST */ + LP_I2C_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< LP_I2C source clock is XTAL */ + LP_I2C_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock default choice is RTC_FAST */ +} soc_periph_lp_i2c_clk_src_t; + /////////////////////////////////////////////////SPI//////////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 2449699a9f..0c8419c1a4 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -60,7 +60,7 @@ #define SOC_GPSPI_SUPPORTED 1 #define SOC_LEDC_SUPPORTED 1 // #define SOC_ISP_SUPPORTED 1 // TODO: [ESP32S31] IDF-14769 -// #define SOC_I2C_SUPPORTED 1 // TODO: [ESP32S31] IDF-14726 +#define SOC_I2C_SUPPORTED 1 #define SOC_SYSTIMER_SUPPORTED 1 // TODO: [ESP32S31] IDF-14693 // #define SOC_AES_SUPPORTED 1 // TODO: [ESP32S31] IDF-14633 // #define SOC_MPI_SUPPORTED 1 // TODO: [ESP32S31] IDF-14633 @@ -79,7 +79,7 @@ // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32S31] IDF-14634 #define SOC_LP_GPIO_MATRIX_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1 -// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32S31] IDF-14635 +#define SOC_LP_I2C_SUPPORTED 1 // #define SOC_LP_SPI_SUPPORTED 1 // TODO: [ESP32S31] IDF-14639 #define SOC_SPIRAM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14718 #define SOC_PSRAM_DMA_CAPABLE 1 @@ -230,6 +230,21 @@ #define SOC_RMT_SUPPORT_DMA 1 /*!< RMT peripheral can connect to DMA channel */ #define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */ +/*-------------------------- I2C CAPS ----------------------------------------*/ +#define SOC_I2C_NUM (3U) +#define SOC_HP_I2C_NUM (2U) +#define SOC_LP_I2C_NUM (1U) + +#define SOC_I2C_SUPPORT_XTAL (1) +#define SOC_I2C_SUPPORT_RTC (1) +#define SOC_I2C_SUPPORT_10BIT_ADDR (1) + +#define SOC_I2C_SUPPORT_SLAVE (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) + +#define SOC_I2C_SUPPORT_SLEEP_RETENTION (1) + /*-------------------------- MMU CAPS ----------------------------------------*/ #define SOC_MMU_PERIPH_NUM (2U) #define SOC_MMU_LINEAR_ADDRESS_REGION_NUM (2U) diff --git a/components/soc/esp32s31/register/soc/i2c_reg.h b/components/soc/esp32s31/register/soc/i2c_reg.h index 8eb5b34924..6ca6bdbd3a 100644 --- a/components/soc/esp32s31/register/soc/i2c_reg.h +++ b/components/soc/esp32s31/register/soc/i2c_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -10,10 +10,12 @@ extern "C" { #endif +#define REG_I2C_BASE(i) (DR_REG_I2C0_BASE + (i) * 0x1000) + /** I2C_SCL_LOW_PERIOD_REG register * Configures the low level width of the SCL Clock */ -#define I2C_SCL_LOW_PERIOD_REG (DR_REG_I2C_BASE + 0x0) +#define I2C_SCL_LOW_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x0) /** I2C_SCL_LOW_PERIOD : R/W; bitpos: [8:0]; default: 0; * Configures the low level width of the SCL Clock in Master mode. * Measurement unit: I2C_SCLK @@ -26,7 +28,7 @@ extern "C" { /** I2C_CTR_REG register * Transmission setting register */ -#define I2C_CTR_REG (DR_REG_I2C_BASE + 0x4) +#define I2C_CTR_REG(i) (REG_I2C_BASE(i) + 0x4) /** I2C_SDA_FORCE_OUT : R/W; bitpos: [0]; default: 0; * Configures the SDA output mode. * 0: Open drain output @@ -166,7 +168,7 @@ extern "C" { /** I2C_SR_REG register * I2C working status register */ -#define I2C_SR_REG (DR_REG_I2C_BASE + 0x8) +#define I2C_SR_REG(i) (REG_I2C_BASE(i) + 0x8) /** I2C_RESP_REC : RO; bitpos: [0]; default: 0; * Represents the received ACK value in Master mode or Slave mode. * 0: ACK @@ -270,7 +272,7 @@ extern "C" { /** I2C_TO_REG register * Timeout control register for receiving data */ -#define I2C_TO_REG (DR_REG_I2C_BASE + 0xc) +#define I2C_TO_REG(i) (REG_I2C_BASE(i) + 0xc) /** I2C_TIME_OUT_VALUE : R/W; bitpos: [4:0]; default: 16; * Configures the timeout threshold period for SCL stucking at high or low level. The * actual period is 2\^{}(reg_time_out_value). @@ -293,7 +295,7 @@ extern "C" { /** I2C_SLAVE_ADDR_REG register * Local slave address setting register */ -#define I2C_SLAVE_ADDR_REG (DR_REG_I2C_BASE + 0x10) +#define I2C_SLAVE_ADDR_REG(i) (REG_I2C_BASE(i) + 0x10) /** I2C_SLAVE_ADDR : R/W; bitpos: [14:0]; default: 0; * Configures the slave address of the I2C slave. */ @@ -314,7 +316,7 @@ extern "C" { /** I2C_FIFO_ST_REG register * FIFO status register */ -#define I2C_FIFO_ST_REG (DR_REG_I2C_BASE + 0x14) +#define I2C_FIFO_ST_REG(i) (REG_I2C_BASE(i) + 0x14) /** I2C_RXFIFO_RADDR : RO; bitpos: [4:0]; default: 0; * Represents the offset address of the APB reading from RX FIFO. */ @@ -355,7 +357,7 @@ extern "C" { /** I2C_FIFO_CONF_REG register * FIFO configuration register */ -#define I2C_FIFO_CONF_REG (DR_REG_I2C_BASE + 0x18) +#define I2C_FIFO_CONF_REG(i) (REG_I2C_BASE(i) + 0x18) /** I2C_RXFIFO_WM_THRHD : R/W; bitpos: [4:0]; default: 11; * Configures the watermark threshold of RX FIFO in non-FIFO access mode. When * I2C_FIFO_PRT_EN is 1 and RX FIFO counter is bigger than I2C_RXFIFO_WM_THRHD[4:0], @@ -425,7 +427,7 @@ extern "C" { /** I2C_DATA_REG register * Rx FIFO read data */ -#define I2C_DATA_REG (DR_REG_I2C_BASE + 0x1c) +#define I2C_DATA_REG(i) (REG_I2C_BASE(i) + 0x1c) /** I2C_FIFO_RDATA : HRO; bitpos: [7:0]; default: 0; * Represents the value of RXFIFO read data. */ @@ -437,7 +439,7 @@ extern "C" { /** I2C_INT_RAW_REG register * Raw interrupt status register */ -#define I2C_INT_RAW_REG (DR_REG_I2C_BASE + 0x20) +#define I2C_INT_RAW_REG(i) (REG_I2C_BASE(i) + 0x20) /** I2C_RXFIFO_WM_INT_RAW : R/SS/WTC; bitpos: [0]; default: 0; * The raw interrupt status of I2C_RXFIFO_WM_INT. */ @@ -575,7 +577,7 @@ extern "C" { /** I2C_INT_CLR_REG register * Interrupt clear register */ -#define I2C_INT_CLR_REG (DR_REG_I2C_BASE + 0x24) +#define I2C_INT_CLR_REG(i) (REG_I2C_BASE(i) + 0x24) /** I2C_RXFIFO_WM_INT_CLR : WT; bitpos: [0]; default: 0; * Write 1 to clear I2C_RXFIFO_WM_INT. */ @@ -713,7 +715,7 @@ extern "C" { /** I2C_INT_ENA_REG register * Interrupt enable register */ -#define I2C_INT_ENA_REG (DR_REG_I2C_BASE + 0x28) +#define I2C_INT_ENA_REG(i) (REG_I2C_BASE(i) + 0x28) /** I2C_RXFIFO_WM_INT_ENA : R/W; bitpos: [0]; default: 0; * Write 1 to enable I2C_RXFIFO_WM_INT. */ @@ -851,7 +853,7 @@ extern "C" { /** I2C_INT_STATUS_REG register * Status register of captured I2C communication events */ -#define I2C_INT_STATUS_REG (DR_REG_I2C_BASE + 0x2c) +#define I2C_INT_STATUS_REG(i) (REG_I2C_BASE(i) + 0x2c) /** I2C_RXFIFO_WM_INT_ST : RO; bitpos: [0]; default: 0; * The masked interrupt status of I2C_RXFIFO_WM_INT. */ @@ -989,7 +991,7 @@ extern "C" { /** I2C_SDA_HOLD_REG register * Configures the hold time after a negative SCL edge */ -#define I2C_SDA_HOLD_REG (DR_REG_I2C_BASE + 0x30) +#define I2C_SDA_HOLD_REG(i) (REG_I2C_BASE(i) + 0x30) /** I2C_SDA_HOLD_TIME : R/W; bitpos: [8:0]; default: 0; * Configures the time to hold the data after the falling edge of SCL. * Measurement unit: I2C_SCLK @@ -1002,7 +1004,7 @@ extern "C" { /** I2C_SDA_SAMPLE_REG register * Configures the sample time after a positive SCL edge */ -#define I2C_SDA_SAMPLE_REG (DR_REG_I2C_BASE + 0x34) +#define I2C_SDA_SAMPLE_REG(i) (REG_I2C_BASE(i) + 0x34) /** I2C_SDA_SAMPLE_TIME : R/W; bitpos: [8:0]; default: 0; * Configures the time for sampling SDA. * Measurement unit: I2C_SCLK @@ -1015,7 +1017,7 @@ extern "C" { /** I2C_SCL_HIGH_PERIOD_REG register * Configures the high level width of SCL */ -#define I2C_SCL_HIGH_PERIOD_REG (DR_REG_I2C_BASE + 0x38) +#define I2C_SCL_HIGH_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x38) /** I2C_SCL_HIGH_PERIOD : R/W; bitpos: [8:0]; default: 0; * Configures for how long SCL remains high in Master mode. * Measurement unit: I2C_SCLK @@ -1036,7 +1038,7 @@ extern "C" { /** I2C_SCL_START_HOLD_REG register * Configures the delay between the SDA and SCL negative edge for a start condition */ -#define I2C_SCL_START_HOLD_REG (DR_REG_I2C_BASE + 0x40) +#define I2C_SCL_START_HOLD_REG(i) (REG_I2C_BASE(i) + 0x40) /** I2C_SCL_START_HOLD_TIME : R/W; bitpos: [8:0]; default: 8; * Configures the time between the falling edge of SDA and the falling edge of SCL for * a START condition. @@ -1050,7 +1052,7 @@ extern "C" { /** I2C_SCL_RSTART_SETUP_REG register * Configures the delay between the positive edge of SCL and the negative edge of SDA */ -#define I2C_SCL_RSTART_SETUP_REG (DR_REG_I2C_BASE + 0x44) +#define I2C_SCL_RSTART_SETUP_REG(i) (REG_I2C_BASE(i) + 0x44) /** I2C_SCL_RSTART_SETUP_TIME : R/W; bitpos: [8:0]; default: 8; * Configures the time between the positive edge of SCL and the negative edge of SDA * for a RESTART condition. @@ -1064,7 +1066,7 @@ extern "C" { /** I2C_SCL_STOP_HOLD_REG register * Configures the delay after the SCL clock edge for a stop condition */ -#define I2C_SCL_STOP_HOLD_REG (DR_REG_I2C_BASE + 0x48) +#define I2C_SCL_STOP_HOLD_REG(i) (REG_I2C_BASE(i) + 0x48) /** I2C_SCL_STOP_HOLD_TIME : R/W; bitpos: [8:0]; default: 8; * Configures the delay after the STOP condition. * Measurement unit: I2C_SCLK @@ -1078,7 +1080,7 @@ extern "C" { * Configures the delay between the SDA and SCL rising edge for a stop condition. * Measurement unit: I2C_SCLK */ -#define I2C_SCL_STOP_SETUP_REG (DR_REG_I2C_BASE + 0x4c) +#define I2C_SCL_STOP_SETUP_REG(i) (REG_I2C_BASE(i) + 0x4c) /** I2C_SCL_STOP_SETUP_TIME : R/W; bitpos: [8:0]; default: 8; * Configures the time between the rising edge of SCL and the rising edge of SDA. * Measurement unit: I2C_SCLK @@ -1091,7 +1093,7 @@ extern "C" { /** I2C_FILTER_CFG_REG register * SCL and SDA filter configuration register */ -#define I2C_FILTER_CFG_REG (DR_REG_I2C_BASE + 0x50) +#define I2C_FILTER_CFG_REG(i) (REG_I2C_BASE(i) + 0x50) /** I2C_SCL_FILTER_THRES : R/W; bitpos: [3:0]; default: 0; * Configures the threshold pulse width to be filtered on SCL. When a pulse on the SCL * input has smaller width than this register value, the I2C controller will ignore @@ -1134,7 +1136,7 @@ extern "C" { /** I2C_COMD0_REG register * I2C command register 0 */ -#define I2C_COMD0_REG (DR_REG_I2C_BASE + 0x58) +#define I2C_COMD0_REG(i) (REG_I2C_BASE(i) + 0x58) /** I2C_COMMAND0 : R/W; bitpos: [13:0]; default: 0; * Configures command 0. * It consists of three parts: @@ -1166,7 +1168,7 @@ extern "C" { /** I2C_COMD1_REG register * I2C command register 1 */ -#define I2C_COMD1_REG (DR_REG_I2C_BASE + 0x5c) +#define I2C_COMD1_REG(i) (REG_I2C_BASE(i) + 0x5c) /** I2C_COMMAND1 : R/W; bitpos: [13:0]; default: 0; * Configures command 1. See details in I2C_COMD0_REG [13:0]. */ @@ -1187,7 +1189,7 @@ extern "C" { /** I2C_COMD2_REG register * I2C command register 2 */ -#define I2C_COMD2_REG (DR_REG_I2C_BASE + 0x60) +#define I2C_COMD2_REG(i) (REG_I2C_BASE(i) + 0x60) /** I2C_COMMAND2 : R/W; bitpos: [13:0]; default: 0; * Configures command 2. See details in I2C_COMD0_REG [13:0]. */ @@ -1208,7 +1210,7 @@ extern "C" { /** I2C_COMD3_REG register * I2C command register 3 */ -#define I2C_COMD3_REG (DR_REG_I2C_BASE + 0x64) +#define I2C_COMD3_REG(i) (REG_I2C_BASE(i) + 0x64) /** I2C_COMMAND3 : R/W; bitpos: [13:0]; default: 0; * Configures command 3. See details in I2C_COMD0_REG [13:0]. */ @@ -1229,7 +1231,7 @@ extern "C" { /** I2C_COMD4_REG register * I2C command register 4 */ -#define I2C_COMD4_REG (DR_REG_I2C_BASE + 0x68) +#define I2C_COMD4_REG(i) (REG_I2C_BASE(i) + 0x68) /** I2C_COMMAND4 : R/W; bitpos: [13:0]; default: 0; * Configures command 4. See details in I2C_COMD0_REG [13:0]. */ @@ -1250,7 +1252,7 @@ extern "C" { /** I2C_COMD5_REG register * I2C command register 5 */ -#define I2C_COMD5_REG (DR_REG_I2C_BASE + 0x6c) +#define I2C_COMD5_REG(i) (REG_I2C_BASE(i) + 0x6c) /** I2C_COMMAND5 : R/W; bitpos: [13:0]; default: 0; * Configures command 5. See details in I2C_COMD0_REG [13:0]. */ @@ -1271,7 +1273,7 @@ extern "C" { /** I2C_COMD6_REG register * I2C command register 6 */ -#define I2C_COMD6_REG (DR_REG_I2C_BASE + 0x70) +#define I2C_COMD6_REG(i) (REG_I2C_BASE(i) + 0x70) /** I2C_COMMAND6 : R/W; bitpos: [13:0]; default: 0; * Configures command 6. See details in I2C_COMD0_REG [13:0]. */ @@ -1292,7 +1294,7 @@ extern "C" { /** I2C_COMD7_REG register * I2C command register 7 */ -#define I2C_COMD7_REG (DR_REG_I2C_BASE + 0x74) +#define I2C_COMD7_REG(i) (REG_I2C_BASE(i) + 0x74) /** I2C_COMMAND7 : R/W; bitpos: [13:0]; default: 0; * Configures command 7. See details in I2C_COMD0_REG [13:0]. */ @@ -1313,7 +1315,7 @@ extern "C" { /** I2C_SCL_ST_TIME_OUT_REG register * SCL status timeout register */ -#define I2C_SCL_ST_TIME_OUT_REG (DR_REG_I2C_BASE + 0x78) +#define I2C_SCL_ST_TIME_OUT_REG(i) (REG_I2C_BASE(i) + 0x78) /** I2C_SCL_ST_TO_I2C : R/W; bitpos: [4:0]; default: 16; * Configures the threshold value of SCL_FSM state unchanged period. It should be no * more than 23, more than 1. @@ -1331,7 +1333,7 @@ extern "C" { /** I2C_SCL_MAIN_ST_TIME_OUT_REG register * SCL main status timeout register */ -#define I2C_SCL_MAIN_ST_TIME_OUT_REG (DR_REG_I2C_BASE + 0x7c) +#define I2C_SCL_MAIN_ST_TIME_OUT_REG(i) (REG_I2C_BASE(i) + 0x7c) /** I2C_SCL_MAIN_ST_TO_I2C : R/W; bitpos: [4:0]; default: 16; * Configures the threshold value of SCL_MAIN_FSM state unchanged period. It should be * no more than 23. @@ -1345,7 +1347,7 @@ extern "C" { /** I2C_SCL_SP_CONF_REG register * Power configuration register */ -#define I2C_SCL_SP_CONF_REG (DR_REG_I2C_BASE + 0x80) +#define I2C_SCL_SP_CONF_REG(i) (REG_I2C_BASE(i) + 0x80) /** I2C_SCL_RST_SLV_EN : R/W/SC; bitpos: [0]; default: 0; * Configures whether or not to send out SCL pulses when I2C master is IDLE. The * number of pulses equals to I2C_SCL_RST_SLV_NUM[4:0]. @@ -1387,7 +1389,7 @@ extern "C" { /** I2C_SCL_STRETCH_CONF_REG register * SCL stretch setting register of I2C slave */ -#define I2C_SCL_STRETCH_CONF_REG (DR_REG_I2C_BASE + 0x84) +#define I2C_SCL_STRETCH_CONF_REG(i) (REG_I2C_BASE(i) + 0x84) /** I2C_STRETCH_PROTECT_NUM : R/W; bitpos: [9:0]; default: 0; * Configures the time period to release the SCL line from stretching to avoid timing * violation. Usually it should be larger than the SDA setup time. @@ -1439,7 +1441,7 @@ extern "C" { /** I2C_DATE_REG register * Version control register */ -#define I2C_DATE_REG (DR_REG_I2C_BASE + 0xf8) +#define I2C_DATE_REG(i) (REG_I2C_BASE(i) + 0xf8) /** I2C_DATE : R/W; bitpos: [31:0]; default: 38817888; * Version control register. */ @@ -1451,7 +1453,7 @@ extern "C" { /** I2C_TXFIFO_START_ADDR_REG register * I2C TXFIFO base address register */ -#define I2C_TXFIFO_START_ADDR_REG (DR_REG_I2C_BASE + 0x100) +#define I2C_TXFIFO_START_ADDR_REG(i) (REG_I2C_BASE(i) + 0x100) /** I2C_TXFIFO_START_ADDR : HRO; bitpos: [31:0]; default: 0; * Represents the I2C TX FIFO first address. */ @@ -1463,7 +1465,7 @@ extern "C" { /** I2C_RXFIFO_START_ADDR_REG register * I2C RXFIFO base address register */ -#define I2C_RXFIFO_START_ADDR_REG (DR_REG_I2C_BASE + 0x180) +#define I2C_RXFIFO_START_ADDR_REG(i) (REG_I2C_BASE(i) + 0x180) /** I2C_RXFIFO_START_ADDR : HRO; bitpos: [31:0]; default: 0; * Represents the I2C RX FIFO first address. */ diff --git a/components/soc/esp32s31/register/soc/i2c_struct.h b/components/soc/esp32s31/register/soc/i2c_struct.h index f4f5b7f926..77d5a40220 100644 --- a/components/soc/esp32s31/register/soc/i2c_struct.h +++ b/components/soc/esp32s31/register/soc/i2c_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -965,176 +965,35 @@ typedef union { /** Group: Command registers */ -/** Type of comd0 register - * I2C command register 0 +/** Type of comd0~7 register + * I2C command register 0~7 */ typedef union { struct { - /** command0 : R/W; bitpos: [13:0]; default: 0; - * Configures command 0. + /** command : R/W; bitpos: [13:0]; default: 0; + * Configures commands 0~7. * It consists of three parts: * op_code is the command - * 0: RSTART + * 6: RSTART * 1: WRITE - * 2: READ - * 3: STOP + * 3: READ + * 2: 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. - * " + * 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; - * Represents whether command 0 is done in I2C Master mode. + /** command_done : R/W/SS; bitpos: [31]; default: 0; + * Represents whether command is done in I2C Master mode. * 0: Not done * 1: Done */ - 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; - * Configures command 1. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command1:14; - uint32_t reserved_14:17; - /** command1_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 1 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 2. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command2:14; - uint32_t reserved_14:17; - /** command2_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 2 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 3. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command3:14; - uint32_t reserved_14:17; - /** command3_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 3 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 4. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command4:14; - uint32_t reserved_14:17; - /** command4_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 4 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 5. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command5:14; - uint32_t reserved_14:17; - /** command5_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 5 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 6. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command6:14; - uint32_t reserved_14:17; - /** command6_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 6 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - 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; - * Configures command 7. See details in I2C_COMD0_REG [13:0]. - */ - uint32_t command7:14; - uint32_t reserved_14:17; - /** command7_done : R/W/SS; bitpos: [31]; default: 0; - * Represents whether command 7 is done in I2C Master mode. - * 0: Not done - * 1: Done - */ - uint32_t command7_done:1; - }; - uint32_t val; -} i2c_comd7_reg_t; +} i2c_comd_reg_t; /** Group: Version register */ @@ -1203,14 +1062,7 @@ typedef struct { volatile i2c_scl_stop_setup_reg_t scl_stop_setup; volatile i2c_filter_cfg_reg_t filter_cfg; uint32_t reserved_054; - 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; @@ -1218,14 +1070,16 @@ 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 I2C0; +extern i2c_dev_t I2C1; +extern i2c_dev_t LP_I2C; #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/esp32s31/register/soc/lp_i2c_ext_reg.h b/components/soc/esp32s31/register/soc/lp_i2c_reg.h similarity index 100% rename from components/soc/esp32s31/register/soc/lp_i2c_ext_reg.h rename to components/soc/esp32s31/register/soc/lp_i2c_reg.h diff --git a/components/soc/esp32s31/register/soc/lp_i2c_ext_struct.h b/components/soc/esp32s31/register/soc/lp_i2c_struct.h similarity index 82% rename from components/soc/esp32s31/register/soc/lp_i2c_ext_struct.h rename to components/soc/esp32s31/register/soc/lp_i2c_struct.h index d3dc78f8e0..cdbc746ca1 100644 --- a/components/soc/esp32s31/register/soc/lp_i2c_ext_struct.h +++ b/components/soc/esp32s31/register/soc/lp_i2c_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -762,173 +762,35 @@ typedef union { /** Group: Command registers */ -/** Type of comd0 register - * I2C command register 0 +/** Type of comd0~7 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: op_code is the - * command, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. + /** command : R/W; bitpos: [13:0]; default: 0; + * Configures command 0. + * 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 highlevel. + /** command_done : R/W/SS; bitpos: [31]; default: 0; + * Represents whether command is done in I2C Master mode. + * 0: Not done + * 1: Done */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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 highlevel. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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 highLevel. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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 highlevel. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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 highlevel. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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, 1: WRITE, 2: STOP, 3: READ, 4: END, 6: RSTART. 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 moreInformation. - */ - 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 */ @@ -997,14 +859,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; @@ -1017,6 +872,8 @@ typedef struct { } i2c_dev_t; +extern i2c_dev_t LP_I2C; + #ifndef __cplusplus _Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); #endif diff --git a/examples/peripherals/i2c/i2c_basic/README.md b/examples/peripherals/i2c/i2c_basic/README.md index 4ae7c6ff08..f0309d91ec 100644 --- a/examples/peripherals/i2c/i2c_basic/README.md +++ b/examples/peripherals/i2c/i2c_basic/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # Basic I2C Master Example diff --git a/examples/peripherals/i2c/i2c_eeprom/README.md b/examples/peripherals/i2c/i2c_eeprom/README.md index f1bb99a215..b934e9d297 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-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # I2C EEPROM example diff --git a/examples/peripherals/i2c/i2c_tools/README.md b/examples/peripherals/i2c/i2c_tools/README.md index fea0552069..5b9994c2ec 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-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # I2C Tools Example diff --git a/examples/peripherals/i2c/i2c_u8g2/README.md b/examples/peripherals/i2c/i2c_u8g2/README.md index 66a77a6373..63fd7fff08 100644 --- a/examples/peripherals/i2c/i2c_u8g2/README.md +++ b/examples/peripherals/i2c/i2c_u8g2/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # I2C U8G2 Display Demo diff --git a/examples/peripherals/lcd/i2c_oled/README.md b/examples/peripherals/lcd/i2c_oled/README.md index 547f4b5cc8..8fb37d33a6 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-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # I2C OLED example