From 060283f782df221ffbd01ffd7968151cc4275261 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Sun, 4 Jan 2026 18:08:22 +0800 Subject: [PATCH] refactor(i3c): Move i3c hal to seperate folder --- components/esp_driver_i3c/CMakeLists.txt | 2 ++ components/esp_driver_i3c/i3c_master.c | 12 +++---- .../esp_driver_i3c/i3c_master_private.h | 4 +-- .../test_apps/i3c_test_apps/CMakeLists.txt | 9 ++++- components/esp_hal_i3c/CMakeLists.txt | 22 ++++++++++++ components/esp_hal_i3c/README.md | 9 +++++ .../esp32p4/i3c_master_periph.c | 6 ++-- .../esp32p4/include/hal/i3c_master_ll.h | 34 ++++++++++--------- .../esp32p4/include/hal}/i3c_master_periph.h | 5 +-- .../esp32p4/include/hal/i3c_slave_ll.h | 3 -- .../{hal => esp_hal_i3c}/i3c_master_hal.c | 0 .../include/hal/i3c_master_hal.h | 0 .../include/hal/i3c_master_types.h | 3 +- components/hal/CMakeLists.txt | 4 --- components/soc/CMakeLists.txt | 4 --- .../esp32p4/include/soc/Kconfig.soc_caps.in | 12 ------- components/soc/esp32p4/include/soc/soc_caps.h | 7 +--- 17 files changed, 75 insertions(+), 61 deletions(-) create mode 100644 components/esp_hal_i3c/CMakeLists.txt create mode 100644 components/esp_hal_i3c/README.md rename components/{soc => esp_hal_i3c}/esp32p4/i3c_master_periph.c (75%) rename components/{hal => esp_hal_i3c}/esp32p4/include/hal/i3c_master_ll.h (98%) rename components/{soc/include/soc => esp_hal_i3c/esp32p4/include/hal}/i3c_master_periph.h (76%) rename components/{hal => esp_hal_i3c}/esp32p4/include/hal/i3c_slave_ll.h (99%) rename components/{hal => esp_hal_i3c}/i3c_master_hal.c (100%) rename components/{hal => esp_hal_i3c}/include/hal/i3c_master_hal.h (100%) rename components/{hal => esp_hal_i3c}/include/hal/i3c_master_types.h (99%) diff --git a/components/esp_driver_i3c/CMakeLists.txt b/components/esp_driver_i3c/CMakeLists.txt index 2d0caf3272..d543f8fe95 100644 --- a/components/esp_driver_i3c/CMakeLists.txt +++ b/components/esp_driver_i3c/CMakeLists.txt @@ -13,10 +13,12 @@ if(${target} STREQUAL "linux") set(priv_requires "") else() set(priv_requires esp_driver_gpio esp_pm esp_mm) + set(requires esp_hal_i3c) endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${include} PRIV_REQUIRES "${priv_requires}" + REQUIRES "${requires}" LDFRAGMENTS "linker.lf" ) diff --git a/components/esp_driver_i3c/i3c_master.c b/components/esp_driver_i3c/i3c_master.c index 4ae86bc961..b6a2f8a97a 100644 --- a/components/esp_driver_i3c/i3c_master.c +++ b/components/esp_driver_i3c/i3c_master.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 */ @@ -39,13 +39,13 @@ #include "hal/i3c_master_ll.h" #include "i3c_master_private.h" #include "soc/clk_tree_defs.h" -#include "soc/i3c_master_periph.h" +#include "hal/i3c_master_periph.h" static const char *TAG = "i3c.master"; typedef struct i3c_master_platform_t { portMUX_TYPE spinlock; // platform level spinlock. - i3c_master_bus_handle_t buses[SOC_I3C_MASTER_PERIPH_NUM]; // array of I3C master bus instances. + i3c_master_bus_handle_t buses[I3C_MASTER_LL_PERIPH_NUM]; // array of I3C master bus instances. } i3c_master_platform_t; static i3c_master_platform_t s_i3c_master_platform = {}; // singleton platform @@ -333,10 +333,10 @@ static esp_err_t i3c_master_async_transaction_preparation(i3c_master_bus_t *i3c_ ESP_RETURN_ON_FALSE(xQueueSend(i3c_master_handle->trans_queues[I3C_TRANS_QUEUE_READY], &p_trans_desc, 0) == pdTRUE, ESP_ERR_INVALID_STATE, TAG, "ready queue full"); } - i3c_master_handle->i3c_async_addr_table = (i3c_master_ll_device_address_descriptor_t(*)[SOC_I3C_MASTER_ADDRESS_TABLE_NUM])heap_caps_calloc(i3c_master_handle->queue_depth, sizeof(*i3c_master_handle->i3c_async_addr_table), I3C_MASTER_MEM_ALLOC_CAPS); + i3c_master_handle->i3c_async_addr_table = (i3c_master_ll_device_address_descriptor_t(*)[I3C_MASTER_LL_ADDRESS_TABLE_NUM])heap_caps_calloc(i3c_master_handle->queue_depth, sizeof(*i3c_master_handle->i3c_async_addr_table), I3C_MASTER_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(i3c_master_handle->i3c_async_addr_table, ESP_ERR_NO_MEM, TAG, "no mem for address table"); - i3c_master_handle->i3c_async_command_table = (i3c_master_ll_command_descriptor_t(*)[SOC_I3C_MASTER_COMMAND_TABLE_NUM])heap_caps_calloc(i3c_master_handle->queue_depth, sizeof(*i3c_master_handle->i3c_async_command_table), I3C_MASTER_MEM_ALLOC_CAPS); + i3c_master_handle->i3c_async_command_table = (i3c_master_ll_command_descriptor_t(*)[I3C_MASTER_LL_COMMAND_TABLE_NUM])heap_caps_calloc(i3c_master_handle->queue_depth, sizeof(*i3c_master_handle->i3c_async_command_table), I3C_MASTER_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(i3c_master_handle->i3c_async_command_table, ESP_ERR_NO_MEM, TAG, "no mem for command table"); i3c_master_handle->ops_prepare_idx = 0; @@ -714,7 +714,7 @@ esp_err_t i3c_new_master_bus(const i3c_master_bus_config_t *bus_config, i3c_mast s_i3c_master_platform.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&s_i3c_master_platform.spinlock); bool bus_found = false; - for (int i = 0; i < SOC_I3C_MASTER_PERIPH_NUM; i++) { + for (int i = 0; i < I3C_MASTER_LL_PERIPH_NUM; i++) { if (i3c_master_bus_occupied(i) == false) { s_i3c_master_platform.buses[i] = i3c_master_handle; bus_found = true; diff --git a/components/esp_driver_i3c/i3c_master_private.h b/components/esp_driver_i3c/i3c_master_private.h index 54a0e4379b..b14c15061b 100644 --- a/components/esp_driver_i3c/i3c_master_private.h +++ b/components/esp_driver_i3c/i3c_master_private.h @@ -170,8 +170,8 @@ struct i3c_master_bus_t { i3c_transaction_desc_t *trans_desc_pool; /**< Pool of pre-allocated transaction descriptors. */ uint32_t ops_prepare_idx; /**< Index for preparing operations. */ bool async_memory_allocated; /**< The async transaction is allocated or not */ - i3c_master_ll_device_address_descriptor_t (*i3c_async_addr_table)[SOC_I3C_MASTER_ADDRESS_TABLE_NUM]; /**< Address table for asynchronous transactions. */ - i3c_master_ll_command_descriptor_t (*i3c_async_command_table)[SOC_I3C_MASTER_COMMAND_TABLE_NUM]; /**< Command table for asynchronous transactions. */ + i3c_master_ll_device_address_descriptor_t (*i3c_async_addr_table)[I3C_MASTER_LL_ADDRESS_TABLE_NUM]; /**< Address table for asynchronous transactions. */ + i3c_master_ll_command_descriptor_t (*i3c_async_command_table)[I3C_MASTER_LL_COMMAND_TABLE_NUM]; /**< Command table for asynchronous transactions. */ QueueHandle_t trans_queues[I3C_TRANS_QUEUE_MAX]; /**< Array of transaction queues for different states. */ intr_handle_t intr_handle; /**< Interrupt handle for I3C interrupts. */ _Atomic i3c_fsm_t fsm; /**< Current state of the I3C finite state machine. */ diff --git a/components/esp_driver_i3c/test_apps/i3c_test_apps/CMakeLists.txt b/components/esp_driver_i3c/test_apps/i3c_test_apps/CMakeLists.txt index f765839284..7a6ffb6ac2 100644 --- a/components/esp_driver_i3c/test_apps/i3c_test_apps/CMakeLists.txt +++ b/components/esp_driver_i3c/test_apps/i3c_test_apps/CMakeLists.txt @@ -13,9 +13,16 @@ project(i3c_master_test) idf_build_get_property(elf EXECUTABLE) if(CONFIG_COMPILER_DUMP_RTL_FILES) + + set(I3C_RTL_DIRS + ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_i3c + ${CMAKE_BINARY_DIR}/esp-idf/hal + ${CMAKE_BINARY_DIR}/esp-idf/esp_hal_i3c + ) + string(JOIN "," I3C_RTL_DIRS_JOINED ${I3C_RTL_DIRS}) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py - --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_i3c/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${I3C_RTL_DIRS_JOINED} --elf-file ${CMAKE_BINARY_DIR}/i3c_master_test.elf find-refs --from-sections=.iram0.text diff --git a/components/esp_hal_i3c/CMakeLists.txt b/components/esp_hal_i3c/CMakeLists.txt new file mode 100644 index 0000000000..9b976dd99b --- /dev/null +++ b/components/esp_hal_i3c/CMakeLists.txt @@ -0,0 +1,22 @@ +idf_build_get_property(target IDF_TARGET) +if(${target} STREQUAL "linux") + return() # This component is not supported by the POSIX/Linux simulator +endif() + +set(includes) + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/include") + list(APPEND includes "${target}/include") +endif() +list(APPEND includes "include") + +set(srcs) + +# I3C related source files +if(CONFIG_SOC_I3C_MASTER_SUPPORTED) + list(APPEND srcs "i3c_master_hal.c" "${target}/i3c_master_periph.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${includes} + REQUIRES soc hal) diff --git a/components/esp_hal_i3c/README.md b/components/esp_hal_i3c/README.md new file mode 100644 index 0000000000..88e7d3efc2 --- /dev/null +++ b/components/esp_hal_i3c/README.md @@ -0,0 +1,9 @@ +# `esp_hal_i3c` + +⚠️ This HAL component is still under heavy development at the moment, so we don't guarantee the stability and backward-compatibility among versions. + +The `esp_hal_i3c` component provides a **Hardware Abstraction Layer** of I3C for all targets supported by ESP-IDF. + +In a broad sense, the HAL layer consists of two sub-layers: HAL (upper) and Low-Level(bottom). The HAL layer defines the steps and data that is required to operate a peripheral (e.g. initialization, parameter settings). The low-level is a translation layer above the register files under the `soc` component, it only covers general conceptions to register configurations. + +The functions in this file mainly provide hardware abstraction for IDF peripheral drivers. For advanced developers, the HAL layer functions can also be directly used to assist in implementing their own drivers. However, it needs to be mentioned again that the interfaces here do not guarantee stability. diff --git a/components/soc/esp32p4/i3c_master_periph.c b/components/esp_hal_i3c/esp32p4/i3c_master_periph.c similarity index 75% rename from components/soc/esp32p4/i3c_master_periph.c rename to components/esp_hal_i3c/esp32p4/i3c_master_periph.c index 274f9f3510..3944a3f8e1 100644 --- a/components/soc/esp32p4/i3c_master_periph.c +++ b/components/esp_hal_i3c/esp32p4/i3c_master_periph.c @@ -1,17 +1,17 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/i3c_master_periph.h" +#include "hal/i3c_master_periph.h" #include "soc/gpio_sig_map.h" #include "soc/interrupts.h" /* Bunch of constants for every I3C peripheral: GPIO signals, irqs, hw addr of registers etc */ -const i3c_master_signal_conn_t i3c_master_periph_signal[SOC_I3C_MASTER_PERIPH_NUM] = { +const i3c_master_signal_conn_t i3c_master_periph_signal[I3C_MASTER_LL_PERIPH_NUM] = { { .module_name = "I3C_MASTER", .sda_out_sig = I3C_MST_SDA_PAD_OUT_IDX, diff --git a/components/hal/esp32p4/include/hal/i3c_master_ll.h b/components/esp_hal_i3c/esp32p4/include/hal/i3c_master_ll.h similarity index 98% rename from components/hal/esp32p4/include/hal/i3c_master_ll.h rename to components/esp_hal_i3c/esp32p4/include/hal/i3c_master_ll.h index 29b7142dbc..d3caca95a8 100644 --- a/components/hal/esp32p4/include/hal/i3c_master_ll.h +++ b/components/esp_hal_i3c/esp32p4/include/hal/i3c_master_ll.h @@ -33,6 +33,9 @@ extern "C" { #define I3C_LL_MASTER_TRANSMIT_INTR (I3C_MST_TX_DATA_BUF_THLD_INT_ENA_M) #define I3C_LL_MASTER_RECEIVE_INTR (I3C_MST_RX_DATA_BUF_THLD_INT_ENA_M) #define I3C_LL_MASTER_INTERNAL_PULLUP_IO_PINS_MASK (BIT64(32) | BIT64(33)) +#define I3C_MASTER_LL_PERIPH_NUM (1) +#define I3C_MASTER_LL_ADDRESS_TABLE_NUM (12) +#define I3C_MASTER_LL_COMMAND_TABLE_NUM (12) #define I3C_MASTER_LL_DEFAULT_SETUP_TIME (600) @@ -308,7 +311,6 @@ typedef struct { uint8_t dynamic_addr; ///< 7-bit dynamic address assigned via DATA/SETDASA } i3c_master_ll_device_char_descriptor_t; - /** * @brief IBI response status * @@ -1065,21 +1067,21 @@ static inline void i3c_master_ll_set_internal_pullup_value(int io, i3c_master_in { HAL_ASSERT(io == 32 || io == 33); switch (value) { - case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_0_3K: - IO_MUX.gpio[io].i3c_ru = 0; - break; - case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_0_6K: - IO_MUX.gpio[io].i3c_ru = 1; - break; - case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_1_2K: - IO_MUX.gpio[io].i3c_ru = 2; - break; - case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_2_4K: - IO_MUX.gpio[io].i3c_ru = 3; - break; - case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_DISABLED: - HAL_ASSERT(false); - break; + case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_0_3K: + IO_MUX.gpio[io].i3c_ru = 0; + break; + case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_0_6K: + IO_MUX.gpio[io].i3c_ru = 1; + break; + case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_1_2K: + IO_MUX.gpio[io].i3c_ru = 2; + break; + case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_2_4K: + IO_MUX.gpio[io].i3c_ru = 3; + break; + case I3C_MASTER_INTERNAL_PULLUP_RESISTOR_DISABLED: + HAL_ASSERT(false); + break; } } diff --git a/components/soc/include/soc/i3c_master_periph.h b/components/esp_hal_i3c/esp32p4/include/hal/i3c_master_periph.h similarity index 76% rename from components/soc/include/soc/i3c_master_periph.h rename to components/esp_hal_i3c/esp32p4/include/hal/i3c_master_periph.h index f0fbcdaab1..2c7f5ca1f0 100644 --- a/components/soc/include/soc/i3c_master_periph.h +++ b/components/esp_hal_i3c/esp32p4/include/hal/i3c_master_periph.h @@ -1,13 +1,14 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include #include "soc/soc_caps.h" +#include "hal/i3c_master_ll.h" #ifdef __cplusplus extern "C" { @@ -24,7 +25,7 @@ typedef struct { const uint8_t irq; } i3c_master_signal_conn_t; -extern const i3c_master_signal_conn_t i3c_master_periph_signal[SOC_I3C_MASTER_PERIPH_NUM]; +extern const i3c_master_signal_conn_t i3c_master_periph_signal[I3C_MASTER_LL_PERIPH_NUM]; #endif diff --git a/components/hal/esp32p4/include/hal/i3c_slave_ll.h b/components/esp_hal_i3c/esp32p4/include/hal/i3c_slave_ll.h similarity index 99% rename from components/hal/esp32p4/include/hal/i3c_slave_ll.h rename to components/esp_hal_i3c/esp32p4/include/hal/i3c_slave_ll.h index 519c9142a0..bbad6af859 100644 --- a/components/hal/esp32p4/include/hal/i3c_slave_ll.h +++ b/components/esp_hal_i3c/esp32p4/include/hal/i3c_slave_ll.h @@ -24,7 +24,6 @@ extern "C" { #define I3C_SLAVE_LL_EVENT_INTR (I3C_SLV_RXPEND_ENA_M | I3C_SLV_TXSEND_ENA_M) - /** * @brief Enable or disable I3C slave bus clock * @@ -70,7 +69,6 @@ static inline void i3c_slave_ll_config_static_address(i3c_slv_dev_t *hw, uint8_t hw->config.saddr = address; } - /** * @brief Get pointer to I3C slave interrupt status register * @@ -82,7 +80,6 @@ static inline volatile void *i3c_slave_ll_get_interrupt_status_reg(i3c_slv_dev_t return &dev->intmasked; } - /** * @brief Clear I3C slave interrupt flags * diff --git a/components/hal/i3c_master_hal.c b/components/esp_hal_i3c/i3c_master_hal.c similarity index 100% rename from components/hal/i3c_master_hal.c rename to components/esp_hal_i3c/i3c_master_hal.c diff --git a/components/hal/include/hal/i3c_master_hal.h b/components/esp_hal_i3c/include/hal/i3c_master_hal.h similarity index 100% rename from components/hal/include/hal/i3c_master_hal.h rename to components/esp_hal_i3c/include/hal/i3c_master_hal.h diff --git a/components/hal/include/hal/i3c_master_types.h b/components/esp_hal_i3c/include/hal/i3c_master_types.h similarity index 99% rename from components/hal/include/hal/i3c_master_types.h rename to components/esp_hal_i3c/include/hal/i3c_master_types.h index 4f6b551bc3..3448e70ac7 100644 --- a/components/hal/include/hal/i3c_master_types.h +++ b/components/esp_hal_i3c/include/hal/i3c_master_types.h @@ -29,13 +29,12 @@ typedef soc_periph_i3c_master_clk_src_t i3c_master_clock_source_t; typedef int i3c_master_clock_source_t; #endif - /** * @brief I3C Common Command Code (CCC) enumeration * * This enumeration defines all I3C CCC command codes as per MIPI I3C specification. */ - typedef enum { +typedef enum { I3C_CCC_ENEC = 0x00, ///< Enable Events Command I3C_CCC_DISEC = 0x01, ///< Disable Events Command I3C_CCC_ENTAS0 = 0x02, ///< Enable Target Activity State 0 diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 19436cefeb..66080586d3 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -75,10 +75,6 @@ elseif(NOT BOOTLOADER_BUILD) list(APPEND srcs "systimer_hal.c") endif() - if(CONFIG_SOC_I3C_MASTER_SUPPORTED) - list(APPEND srcs "i3c_master_hal.c") - endif() - if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) list(APPEND srcs "sdmmc_hal.c") endif() diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 626d9bc8ba..4ced5ed8d4 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -66,10 +66,6 @@ if(CONFIG_SOC_DEBUG_PROBE_SUPPORTED) list(APPEND srcs "${target_folder}/debug_probe_periph.c") endif() -if(CONFIG_SOC_I3C_MASTER_SUPPORTED) - list(APPEND srcs "${target_folder}/i3c_master_periph.c") -endif() - if(CONFIG_SOC_MPI_SUPPORTED) list(APPEND srcs "${target_folder}/mpi_periph.c") endif() diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 5280a1e8c7..e634ae685d 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1939,18 +1939,6 @@ config SOC_LCDCAM_CAM_SUPPORT_RGB_YUV_CONV bool default y -config SOC_I3C_MASTER_PERIPH_NUM - bool - default y - -config SOC_I3C_MASTER_ADDRESS_TABLE_NUM - int - default 12 - -config SOC_I3C_MASTER_COMMAND_TABLE_NUM - int - default 12 - config SOC_LP_CORE_SUPPORT_ETM bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 796f9c15c0..1413fe0433 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -740,11 +740,6 @@ /*--------------------------- CAM ---------------------------------*/ #define SOC_LCDCAM_CAM_SUPPORT_RGB_YUV_CONV (1) -/*--------------------------- I3C ---------------------------------*/ -#define SOC_I3C_MASTER_PERIPH_NUM (1) -#define SOC_I3C_MASTER_ADDRESS_TABLE_NUM (12) -#define SOC_I3C_MASTER_COMMAND_TABLE_NUM (12) - /*------------------------------------- ULP CAPS -------------------------------------*/ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */ #define SOC_LP_CORE_SUPPORT_LP_ADC (1) /*!< LP ADC can be accessed from the LP-Core */