From 7fe40f12bafcf5a77d2e2180639c954aea7cc09e Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 24 Nov 2025 14:57:25 +0800 Subject: [PATCH] feat(mspi): supported mspi flash and psram isr --- components/esp_hal_mspi/CMakeLists.txt | 8 + .../esp_hal_mspi/esp32/include/hal/mspi_ll.h | 2 + components/esp_hal_mspi/esp32/mspi_periph.c | 28 ++++ .../esp32c2/include/hal/mspi_ll.h | 2 + components/esp_hal_mspi/esp32c2/mspi_periph.c | 27 ++++ .../esp32c3/include/hal/mspi_ll.h | 2 + components/esp_hal_mspi/esp32c3/mspi_periph.c | 27 ++++ .../esp32c5/include/hal/mspi_ll.h | 57 +++++++ .../esp32c5/include/hal/psram_ctrlr_ll.h | 15 ++ components/esp_hal_mspi/esp32c5/mspi_periph.c | 27 ++++ .../esp32c6/include/hal/mspi_ll.h | 2 + components/esp_hal_mspi/esp32c6/mspi_periph.c | 27 ++++ .../esp32c61/include/hal/mspi_ll.h | 56 +++++++ .../esp32c61/include/hal/psram_ctrlr_ll.h | 15 ++ .../esp_hal_mspi/esp32c61/mspi_periph.c | 27 ++++ .../esp32h2/include/hal/mspi_ll.h | 3 + components/esp_hal_mspi/esp32h2/mspi_periph.c | 27 ++++ .../esp32h21/include/hal/mspi_ll.h | 3 + .../esp_hal_mspi/esp32h21/mspi_periph.c | 27 ++++ .../esp32h4/include/hal/mspi_ll.h | 60 ++++++++ .../esp32h4/include/hal/psram_ctrlr_ll.h | 15 ++ components/esp_hal_mspi/esp32h4/mspi_periph.c | 27 ++++ .../esp32p4/include/hal/mspi_ll.h | 59 ++++++++ .../esp32p4/include/hal/psram_ctrlr_ll.h | 59 ++++++++ components/esp_hal_mspi/esp32p4/mspi_periph.c | 33 +++++ .../esp32s2/include/hal/mspi_ll.h | 2 + components/esp_hal_mspi/esp32s2/mspi_periph.c | 27 ++++ .../esp32s3/include/hal/mspi_ll.h | 47 ++++++ .../esp32s3/include/hal/psram_ctrlr_ll.h | 2 + components/esp_hal_mspi/esp32s3/mspi_periph.c | 27 ++++ .../esp32s31/include/hal/mspi_ll.h | 75 ++++++++++ .../esp_hal_mspi/esp32s31/mspi_periph.c | 33 +++++ .../esp_hal_mspi/include/hal/mspi_periph.h | 27 ++++ components/esp_hw_support/CMakeLists.txt | 30 ++-- components/esp_hw_support/README.md | 123 +++++++++++++++ .../{mspi_timing_tuning => mspi}/linker.lf | 0 .../mspi_intr/include/esp_private/mspi_intr.h | 59 ++++++++ .../esp_hw_support/mspi/mspi_intr/mspi_intr.c | 140 ++++++++++++++++++ .../include/esp_private/mspi_timing_config.h | 0 .../include/esp_private/mspi_timing_tuning.h | 0 .../include/esp_private/mspi_timing_types.h | 0 .../mspi_timing_tuning/mspi_timing_tuning.c | 0 .../port/esp32c5/CMakeLists.txt | 0 .../port/esp32c5/mspi_timing_config.c | 0 .../port/esp32c5/mspi_timing_tuning_configs.h | 0 .../port/esp32c61/CMakeLists.txt | 0 .../port/esp32c61/mspi_timing_config.c | 0 .../esp32c61/mspi_timing_tuning_configs.h | 0 .../port/esp32p4/CMakeLists.txt | 0 .../port/esp32p4/mspi_timing_config.c | 0 .../port/esp32p4/mspi_timing_tuning_configs.h | 0 .../port/esp32s3/CMakeLists.txt | 0 .../port/esp32s3/mspi_timing_by_mspi_delay.c | 0 .../port/esp32s3/mspi_timing_config.c | 0 .../port/esp32s3/mspi_timing_tuning_configs.h | 0 .../include/esp_private/mspi_timing_by_dqs.h | 0 .../esp_private/mspi_timing_by_flash_delay.h | 0 .../esp_private/mspi_timing_by_mspi_delay.h | 0 .../esp_private/mspi_timing_impl_types.h | 0 .../tuning_scheme_impl/mspi_timing_by_dqs.c | 0 .../mspi_timing_by_flash_delay.c | 0 .../mspi_timing_by_mspi_delay.c | 0 components/esp_psram/CMakeLists.txt | 2 +- components/esp_psram/README.md | 16 ++ .../include/esp_private/esp_psram_mspi.h | 39 +++++ components/esp_psram/system_layer/esp_psram.c | 18 ++- .../esp_psram/system_layer/esp_psram_mspi.c | 126 ++++++++++++++++ components/esp_system/startup_funcs.c | 13 +- components/esp_system/system_init_fn.txt | 16 +- .../esp32s31/register/soc/spi_mem_s_struct.h | 1 + 70 files changed, 1432 insertions(+), 26 deletions(-) create mode 100644 components/esp_hal_mspi/esp32/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32c2/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32c3/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32c5/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32c6/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32c61/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32h2/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32h21/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32h4/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32p4/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32s2/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32s3/mspi_periph.c create mode 100644 components/esp_hal_mspi/esp32s31/mspi_periph.c create mode 100644 components/esp_hal_mspi/include/hal/mspi_periph.h rename components/esp_hw_support/{mspi_timing_tuning => mspi}/linker.lf (100%) create mode 100644 components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h create mode 100644 components/esp_hw_support/mspi/mspi_intr/mspi_intr.c rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/include/esp_private/mspi_timing_config.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/include/esp_private/mspi_timing_types.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/mspi_timing_tuning.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c5/CMakeLists.txt (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c61/CMakeLists.txt (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32p4/CMakeLists.txt (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32s3/CMakeLists.txt (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c (100%) rename components/esp_hw_support/{ => mspi}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c (100%) create mode 100644 components/esp_psram/README.md create mode 100644 components/esp_psram/include/esp_private/esp_psram_mspi.h create mode 100644 components/esp_psram/system_layer/esp_psram_mspi.c diff --git a/components/esp_hal_mspi/CMakeLists.txt b/components/esp_hal_mspi/CMakeLists.txt index c8d73fe378..ae65f14e78 100644 --- a/components/esp_hal_mspi/CMakeLists.txt +++ b/components/esp_hal_mspi/CMakeLists.txt @@ -1,6 +1,12 @@ idf_build_get_property(target IDF_TARGET) idf_build_get_property(esp_tee_build ESP_TEE_BUILD) +if(${target} STREQUAL "linux") + idf_component_register(INCLUDE_DIRS "include" + REQUIRES soc hal) + return() +endif() + set(srcs) set(includes "include" "${target}/include") @@ -24,6 +30,8 @@ elseif(NOT BOOTLOADER_BUILD) endif() +list(APPEND srcs "${target}/mspi_periph.c") + idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${includes} diff --git a/components/esp_hal_mspi/esp32/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32/include/hal/mspi_ll.h index 8e45e49631..0483a883b6 100644 --- a/components/esp_hal_mspi/esp32/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32/include/hal/mspi_ll.h @@ -17,3 +17,5 @@ */ //For compatibility +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 diff --git a/components/esp_hal_mspi/esp32/mspi_periph.c b/components/esp_hal_mspi/esp32/mspi_periph.c new file mode 100644 index 0000000000..462c6fa102 --- /dev/null +++ b/components/esp_hal_mspi/esp32/mspi_periph.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" +#include "soc/interrupts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_SPI0_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c2/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c2/include/hal/mspi_ll.h index 8e45e49631..0483a883b6 100644 --- a/components/esp_hal_mspi/esp32c2/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c2/include/hal/mspi_ll.h @@ -17,3 +17,5 @@ */ //For compatibility +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 diff --git a/components/esp_hal_mspi/esp32c2/mspi_periph.c b/components/esp_hal_mspi/esp32c2/mspi_periph.c new file mode 100644 index 0000000000..d47ed85b76 --- /dev/null +++ b/components/esp_hal_mspi/esp32c2/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = -1, + }, + [1] = { + .irq = ETS_SPI1_INTR_SOURCE, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c3/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c3/include/hal/mspi_ll.h index 8e45e49631..0483a883b6 100644 --- a/components/esp_hal_mspi/esp32c3/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c3/include/hal/mspi_ll.h @@ -17,3 +17,5 @@ */ //For compatibility +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 diff --git a/components/esp_hal_mspi/esp32c3/mspi_periph.c b/components/esp_hal_mspi/esp32c3/mspi_periph.c new file mode 100644 index 0000000000..d47ed85b76 --- /dev/null +++ b/components/esp_hal_mspi/esp32c3/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = -1, + }, + [1] = { + .irq = ETS_SPI1_INTR_SOURCE, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h index c05190d42b..df6c7d1da4 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h @@ -32,12 +32,29 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 2 #define MSPI_TIMING_LL_MSPI_ID_0 0 #define MSPI_TIMING_LL_MSPI_ID_1 1 #define MSPI_LL_CORE_CLOCK_80_MHZ 80 #define MSPI_LL_CORE_CLOCK_120_MHZ 120 #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ +#define MSPI_LL_ADDR_INT_SUPPORTED 1 +#define MSPI_LL_PMS_INT_SUPPORTED 1 +#define MSPI_LL_ECC_INT_SUPPORTED 1 +#define MSPI_LL_EVENT_SLV_ST_END (1<<3) +#define MSPI_LL_EVENT_MST_ST_END (1<<4) +#define MSPI_LL_EVENT_ECC_ERR (1<<5) +#define MSPI_LL_EVENT_PMS_REJECT (1<<6) +#define MSPI_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define MSPI_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define MSPI_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define MSPI_LL_EVENT_MASK (MSPI_LL_EVENT_ECC_ERR | MSPI_LL_EVENT_PMS_REJECT | MSPI_LL_EVENT_AXI_RADDR_ERR | \ + MSPI_LL_EVENT_AXI_WR_FLASH_ERR | MSPI_LL_EVENT_AXI_WADDR_ERR) + +#define MSPI_LL_INTR_EVENT_SUPPORTED 1 +#define MSPI_LL_INTR_SHARED 1 + /*--------------------------------------------------------------- MSPI ---------------------------------------------------------------*/ @@ -442,6 +459,46 @@ static inline void mspi_timing_ll_get_psram_dummy(uint8_t mspi_id, int *usr_rdum *extra_dummy = REG_GET_FIELD(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_EXTRA_DUMMY_CYCLELEN); } +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.mem_int_ena.val |= intr_mask; + } else { + SPIMEM0.mem_int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.mem_int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.mem_int_raw.val; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h index 371c494c62..71b722efb2 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h @@ -29,12 +29,27 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_0 0 #define PSRAM_CTRLR_LL_MSPI_ID_1 1 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_0 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M #define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 #define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) #define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) +#define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_EVENT_SLV_ST_END (1<<3) +#define PSRAM_CTRLR_LL_EVENT_MST_ST_END (1<<4) +#define PSRAM_CTRLR_LL_EVENT_ECC_ERR (1<<5) +#define PSRAM_CTRLR_LL_EVENT_PMS_REJECT (1<<6) +#define PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define PSRAM_CTRLR_LL_EVENT_MASK (PSRAM_CTRLR_LL_EVENT_ECC_ERR | PSRAM_CTRLR_LL_EVENT_PMS_REJECT | PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR | \ + PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR | PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR) + +#define PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED 1 + /** * @brief PSRAM enum for cs id. */ diff --git a/components/esp_hal_mspi/esp32c5/mspi_periph.c b/components/esp_hal_mspi/esp32c5/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32c5/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c6/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c6/include/hal/mspi_ll.h index 8e45e49631..0483a883b6 100644 --- a/components/esp_hal_mspi/esp32c6/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c6/include/hal/mspi_ll.h @@ -17,3 +17,5 @@ */ //For compatibility +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 diff --git a/components/esp_hal_mspi/esp32c6/mspi_periph.c b/components/esp_hal_mspi/esp32c6/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32c6/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h index 3a8a52275f..b2e54ede98 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h @@ -32,12 +32,28 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 2 #define MSPI_TIMING_LL_MSPI_ID_0 0 #define MSPI_TIMING_LL_MSPI_ID_1 1 #define MSPI_LL_CORE_CLOCK_80_MHZ 80 #define MSPI_LL_CORE_CLOCK_120_MHZ 120 #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ +#define MSPI_LL_EVENT_SLV_ST_END (1<<3) +#define MSPI_LL_EVENT_MST_ST_END (1<<4) +#define MSPI_LL_EVENT_ECC_ERR (1<<5) +#define MSPI_LL_EVENT_PMS_REJECT (1<<6) +#define MSPI_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define MSPI_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define MSPI_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define MSPI_LL_EVENT_MASK (MSPI_LL_EVENT_ECC_ERR | MSPI_LL_EVENT_PMS_REJECT | MSPI_LL_EVENT_AXI_RADDR_ERR | \ + MSPI_LL_EVENT_AXI_WR_FLASH_ERR | MSPI_LL_EVENT_AXI_WADDR_ERR) + +#define MSPI_LL_ADDR_INT_SUPPORTED 1 +#define MSPI_LL_PMS_INT_SUPPORTED 1 +#define MSPI_LL_INTR_EVENT_SUPPORTED 1 +#define MSPI_LL_INTR_SHARED 1 + /************************** MSPI pll clock configurations **************************/ /* @@ -426,6 +442,46 @@ static inline void mspi_timing_ll_get_psram_dummy(uint8_t mspi_id, int *usr_rdum *extra_dummy = REG_GET_FIELD(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_EXTRA_DUMMY_CYCLELEN); } +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.mem_int_ena.val |= intr_mask; + } else { + SPIMEM0.mem_int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.mem_int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.mem_int_raw.val; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h index 371c494c62..71b722efb2 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h @@ -29,12 +29,27 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_0 0 #define PSRAM_CTRLR_LL_MSPI_ID_1 1 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_0 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M #define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 #define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) #define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) +#define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_EVENT_SLV_ST_END (1<<3) +#define PSRAM_CTRLR_LL_EVENT_MST_ST_END (1<<4) +#define PSRAM_CTRLR_LL_EVENT_ECC_ERR (1<<5) +#define PSRAM_CTRLR_LL_EVENT_PMS_REJECT (1<<6) +#define PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define PSRAM_CTRLR_LL_EVENT_MASK (PSRAM_CTRLR_LL_EVENT_ECC_ERR | PSRAM_CTRLR_LL_EVENT_PMS_REJECT | PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR | \ + PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR | PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR) + +#define PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED 1 + /** * @brief PSRAM enum for cs id. */ diff --git a/components/esp_hal_mspi/esp32c61/mspi_periph.c b/components/esp_hal_mspi/esp32c61/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32c61/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32h2/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32h2/include/hal/mspi_ll.h index 43282a85c4..9a68da2958 100644 --- a/components/esp_hal_mspi/esp32h2/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32h2/include/hal/mspi_ll.h @@ -30,6 +30,9 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 + //Timing tuning not applied, and flash has its own clock source. Can change flash clock source #define MSPI_TIMING_LL_FLASH_CLK_SRC_CHANGEABLE 1 diff --git a/components/esp_hal_mspi/esp32h2/mspi_periph.c b/components/esp_hal_mspi/esp32h2/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32h2/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h index 0796ca8854..0060a2324b 100644 --- a/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h @@ -30,6 +30,9 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 + //Timing tuning not applied, and flash has its own clock source. Can change flash clock source #define MSPI_TIMING_LL_FLASH_CLK_SRC_CHANGEABLE 1 diff --git a/components/esp_hal_mspi/esp32h21/mspi_periph.c b/components/esp_hal_mspi/esp32h21/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32h21/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h index 91cbd8afa7..d27ec8e449 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h @@ -23,9 +23,29 @@ #include "soc/soc.h" #include "soc/clk_tree_defs.h" #include "soc/pcr_struct.h" +#include "soc/spi_mem_struct.h" #include "hal/misc.h" #include "hal/assert.h" +#define MSPI_LL_ADDR_INT_SUPPORTED 1 +#define MSPI_LL_PMS_INT_SUPPORTED 1 +#define MSPI_LL_ECC_INT_SUPPORTED 1 +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_TIMING_LL_MSPI_ID_0 0 +#define MSPI_TIMING_LL_MSPI_ID_1 1 +#define MSPI_LL_EVENT_SLV_ST_END (1<<3) +#define MSPI_LL_EVENT_MST_ST_END (1<<4) +#define MSPI_LL_EVENT_ECC_ERR (1<<5) +#define MSPI_LL_EVENT_PMS_REJECT (1<<6) +#define MSPI_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define MSPI_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define MSPI_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define MSPI_LL_EVENT_MASK (MSPI_LL_EVENT_ECC_ERR | MSPI_LL_EVENT_PMS_REJECT | MSPI_LL_EVENT_AXI_RADDR_ERR | \ + MSPI_LL_EVENT_AXI_WR_FLASH_ERR | MSPI_LL_EVENT_AXI_WADDR_ERR) + +#define MSPI_LL_INTR_EVENT_SUPPORTED 1 +#define MSPI_LL_INTR_SHARED 1 + #ifdef __cplusplus extern "C" { #endif @@ -60,6 +80,46 @@ static inline void _mspi_timing_ll_set_flash_clk_src(uint32_t mspi_id, soc_perip } } +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.int_ena.val |= intr_mask; + } else { + SPIMEM0.int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.int_raw.val; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h index 6c8ee10056..9071436ed3 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h @@ -29,12 +29,27 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_0 0 #define PSRAM_CTRLR_LL_MSPI_ID_1 1 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_0 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M #define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 #define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) #define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) +#define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_EVENT_SLV_ST_END (1<<3) +#define PSRAM_CTRLR_LL_EVENT_MST_ST_END (1<<4) +#define PSRAM_CTRLR_LL_EVENT_ECC_ERR (1<<5) +#define PSRAM_CTRLR_LL_EVENT_PMS_REJECT (1<<6) +#define PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define PSRAM_CTRLR_LL_EVENT_MASK (PSRAM_CTRLR_LL_EVENT_ECC_ERR | PSRAM_CTRLR_LL_EVENT_PMS_REJECT | PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR | \ + PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR | PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR) + +#define PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED 1 + /** * @brief PSRAM enum for cs id. */ diff --git a/components/esp_hal_mspi/esp32h4/mspi_periph.c b/components/esp_hal_mspi/esp32h4/mspi_periph.c new file mode 100644 index 0000000000..2341ffd75d --- /dev/null +++ b/components/esp_hal_mspi/esp32h4/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h index 4c0069fd9f..9a71ff66c3 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h @@ -43,6 +43,7 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 4 #define MSPI_TIMING_LL_MSPI_ID_0 0 #define MSPI_TIMING_LL_MSPI_ID_1 1 @@ -59,7 +60,25 @@ extern "C" { #define MSPI_TIMING_LL_FLASH_FAST_MODE_MASK (SPI_MEM_C_FASTRD_MODE) #define MSPI_TIMING_LL_FLASH_SLOW_MODE_MASK 0 +#define MSPI_LL_ADDR_INT_SUPPORTED 1 +#define MSPI_LL_PMS_INT_SUPPORTED 1 +#define MSPI_LL_ECC_INT_SUPPORTED 1 +#define MSPI_LL_FLASH_THRESH_INT_SUPPORTED 1 +#define MSPI_LL_EVENT_SLV_ST_END (1<<3) +#define MSPI_LL_EVENT_MST_ST_END (1<<4) +#define MSPI_LL_EVENT_ECC_ERR (1<<5) +#define MSPI_LL_EVENT_PMS_REJECT (1<<6) +#define MSPI_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define MSPI_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define MSPI_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define MSPI_LL_EVENT_RX_TRANS_OVF (1<<26) +#define MSPI_LL_EVENT_TX_TRANS_UDF (1<<27) +#define MSPI_LL_EVENT_MASK (MSPI_LL_EVENT_ECC_ERR | MSPI_LL_EVENT_PMS_REJECT | MSPI_LL_EVENT_AXI_RADDR_ERR | \ + MSPI_LL_EVENT_AXI_WR_FLASH_ERR | MSPI_LL_EVENT_AXI_WADDR_ERR | MSPI_LL_EVENT_RX_TRANS_OVF | \ + MSPI_LL_EVENT_TX_TRANS_UDF) + #define MSPI_LL_AXI_DISABLE_SUPPORTED 1 +#define MSPI_LL_INTR_EVENT_SUPPORTED 1 /** * MSPI DQS ID @@ -636,6 +655,46 @@ static inline uint32_t mspi_timing_ll_get_invalid_dqs_mask(uint8_t spi_num) } } +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.int_ena.val |= intr_mask; + } else { + SPIMEM0.int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.int_raw.val; +} + /** * Enable AXI access to flash * diff --git a/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h index b4ea66fa33..775e3d58f7 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h @@ -33,6 +33,8 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_2 2 #define PSRAM_CTRLR_LL_MSPI_ID_3 3 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_2 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_3 #define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 #define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) @@ -40,6 +42,23 @@ extern "C" { #define PSRAM_CTRLR_LL_FIFO_MAX_BYTES 64 +#define PSRAM_CTRLR_LL_THRESH_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_EVENT_SLV_ST_END (1<<3) +#define PSRAM_CTRLR_LL_EVENT_MST_ST_END (1<<4) +#define PSRAM_CTRLR_LL_EVENT_ECC_ERR (1<<5) +#define PSRAM_CTRLR_LL_EVENT_PMS_REJECT (1<<6) +#define PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define PSRAM_CTRLR_LL_EVENT_RX_TRANS_OVF (1<<26) +#define PSRAM_CTRLR_LL_EVENT_TX_TRANS_UDF (1<<27) +#define PSRAM_CTRLR_LL_EVENT_MASK (PSRAM_CTRLR_LL_EVENT_ECC_ERR | PSRAM_CTRLR_LL_EVENT_PMS_REJECT | PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR | \ + PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR | PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR | PSRAM_CTRLR_LL_EVENT_RX_TRANS_OVF | \ + PSRAM_CTRLR_LL_EVENT_TX_TRANS_UDF) + +#define PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED 1 + /** * @brief Set PSRAM write cmd * @@ -829,6 +848,46 @@ static inline void psram_ctrlr_ll_wait_all_transaction_done(void) } } +/** + * @brief Enable/Disable PSRAM controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_intr(uint32_t mspi_id, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM2.mem_int_ena.val |= intr_mask; + } else { + SPIMEM2.mem_int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear PSRAM controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_clear_intr(uint32_t mspi_id, uint32_t intr_mask) +{ + SPIMEM2.mem_int_clr.val = intr_mask; +} + +/** + * @brief Get PSRAM controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t psram_ctrlr_ll_get_intr_raw(uint32_t mspi_id) +{ + return SPIMEM2.mem_int_raw.val; +} + /** * @brief Backup PSRAM controller registers * diff --git a/components/esp_hal_mspi/esp32p4/mspi_periph.c b/components/esp_hal_mspi/esp32p4/mspi_periph.c new file mode 100644 index 0000000000..3456c9a41c --- /dev/null +++ b/components/esp_hal_mspi/esp32p4/mspi_periph.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + [2] = { + .irq = ETS_PSRAM_MSPI_INTR_SOURCE, + }, + [3] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32s2/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32s2/include/hal/mspi_ll.h index 8e45e49631..0483a883b6 100644 --- a/components/esp_hal_mspi/esp32s2/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32s2/include/hal/mspi_ll.h @@ -17,3 +17,5 @@ */ //For compatibility +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_LL_INTR_SHARED 1 diff --git a/components/esp_hal_mspi/esp32s2/mspi_periph.c b/components/esp_hal_mspi/esp32s2/mspi_periph.c new file mode 100644 index 0000000000..d47ed85b76 --- /dev/null +++ b/components/esp_hal_mspi/esp32s2/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = -1, + }, + [1] = { + .irq = ETS_SPI1_INTR_SOURCE, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32s3/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32s3/include/hal/mspi_ll.h index 8578af0142..8bf9a62c0d 100644 --- a/components/esp_hal_mspi/esp32s3/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32s3/include/hal/mspi_ll.h @@ -30,6 +30,7 @@ #include "hal/assert.h" #include "soc/soc.h" #include "soc/spi_mem_reg.h" +#include "soc/spi_mem_struct.h" #include "soc/io_mux_reg.h" #include "soc/syscon_struct.h" @@ -37,6 +38,10 @@ extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 2 +#define MSPI_TIMING_LL_MSPI_ID_0 0 +#define MSPI_TIMING_LL_MSPI_ID_1 1 + #define ARRAY_SIZE(arr) (sizeof((arr))/sizeof(*(arr))) #define MSPI_TIMING_LL_FLASH_OCT_MASK (SPI_MEM_FCMD_OCT | SPI_MEM_FADDR_OCT | SPI_MEM_FDIN_OCT | SPI_MEM_FDOUT_OCT) #define MSPI_TIMING_LL_FLASH_QUAD_MASK (SPI_MEM_FASTRD_MODE | SPI_MEM_FREAD_DUAL | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_QIO) @@ -50,6 +55,8 @@ extern "C" { #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT 80 #define MSPI_TIMING_LL_FLASH_CPU_CLK_SRC_BINDED 1 +#define MSPI_LL_INTR_SHARED 1 +#define MSPI_LL_EVENT_MASK 0 typedef enum { MSPI_TIMING_LL_FLASH_OPI_MODE = BIT(0), @@ -562,6 +569,46 @@ static inline void mspi_ll_set_flash_protection_access(uint8_t spi_num, uint32_t } } +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.int_ena.val |= intr_mask; + } else { + SPIMEM0.int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.int_raw.val; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32s3/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32s3/include/hal/psram_ctrlr_ll.h index 8cf34d1f7d..505215548e 100644 --- a/components/esp_hal_mspi/esp32s3/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32s3/include/hal/psram_ctrlr_ll.h @@ -29,6 +29,8 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_0 0 #define PSRAM_CTRLR_LL_MSPI_ID_1 1 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_0 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M diff --git a/components/esp_hal_mspi/esp32s3/mspi_periph.c b/components/esp_hal_mspi/esp32s3/mspi_periph.c new file mode 100644 index 0000000000..d47ed85b76 --- /dev/null +++ b/components/esp_hal_mspi/esp32s3/mspi_periph.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = -1, + }, + [1] = { + .irq = ETS_SPI1_INTR_SOURCE, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h index ad51f34a1a..b06aa93d4c 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h @@ -31,13 +31,88 @@ #include "soc/soc.h" #include "soc/spi_mem_reg.h" #include "soc/io_mux_reg.h" +#include "soc/spi_mem_struct.h" +#include "soc/spi_mem_s_struct.h" +#include "soc/spi_mem_c_reg.h" +#include "soc/spi1_mem_c_reg.h" #ifdef __cplusplus extern "C" { #endif +#define MSPI_LL_PERIPH_NUM 4 +#define MSPI_TIMING_LL_MSPI_ID_0 0 +#define MSPI_TIMING_LL_MSPI_ID_1 1 + +#define MSPI_LL_AXI_DISABLE_SUPPORTED 1 +#define MSPI_LL_INTR_EVENT_SUPPORTED 1 + // TODO: ["ESP32S31"] IDF-14653 +/** + * @brief Enable/Disable MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_enable_intr(uint8_t spi_num, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM0.mem_int_ena.val |= intr_mask; + } else { + SPIMEM0.mem_int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear MSPI controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void mspi_ll_clear_intr(uint8_t spi_num, uint32_t intr_mask) +{ + SPIMEM0.mem_int_clr.val = intr_mask; +} + +/** + * @brief Get MSPI controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_get_intr_raw(uint8_t spi_num) +{ + return SPIMEM0.mem_int_raw.val; +} + +/** + * Enable AXI access to flash + * + * @param spi_num SPI0 / SPI1 + * @param enable Enable / Disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_flash_enable_axi_access(uint8_t spi_num, bool enable) +{ + SPIMEM0.mem_cache_fctrl.close_axi_inf_en = !enable; +} + +/** + * Enable AXI access to PSRAM + * + * @param spi_num SPI0 / SPI1 + * @param enable Enable / Disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_psram_enable_axi_access(uint8_t spi_num, bool enable) +{ + SPIMEM2.mem_cache_fctrl.close_axi_inf_en = !enable; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32s31/mspi_periph.c b/components/esp_hal_mspi/esp32s31/mspi_periph.c new file mode 100644 index 0000000000..e1a63b9f80 --- /dev/null +++ b/components/esp_hal_mspi/esp32s31/mspi_periph.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/periph_defs.h" +#include "hal/mspi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const mspi_info_t mspi_hw_info = { + .instances = { + [0] = { + .irq = ETS_MSPI_FLASH_INTR_SOURCE, + }, + [1] = { + .irq = -1, + }, + [2] = { + .irq = ETS_MSPI_PSRAM_INTR_SOURCE, + }, + [3] = { + .irq = -1, + }, + } +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/include/hal/mspi_periph.h b/components/esp_hal_mspi/include/hal/mspi_periph.h new file mode 100644 index 0000000000..e873f60601 --- /dev/null +++ b/components/esp_hal_mspi/include/hal/mspi_periph.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "hal/mspi_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + struct { + const uint32_t irq; //irq source for interrupt mux + } instances[MSPI_LL_PERIPH_NUM]; +} mspi_info_t; + +extern const mspi_info_t mspi_hw_info; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 3b79542285..f034221143 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -144,19 +144,24 @@ if(NOT non_os_build) endif() if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - list(APPEND srcs "mspi_timing_tuning/mspi_timing_tuning.c") + list(APPEND srcs "mspi/mspi_timing_tuning/mspi_timing_tuning.c") if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY AND NOT CONFIG_IDF_TARGET_ESP32S3) - if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") + set(mspi_delay_file + "${CMAKE_CURRENT_LIST_DIR}/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c" + ) + if(EXISTS "${mspi_delay_file}") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") endif() endif() if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") endif() if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") endif() + + list(APPEND srcs "mspi/mspi_intr/mspi_intr.c") endif() if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED AND CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB) @@ -179,15 +184,15 @@ else() if(ESP_TEE_BUILD) list(APPEND srcs "esp_clk.c" "hw_random.c") if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1) - list(APPEND srcs "mspi_timing_tuning/mspi_timing_tuning.c") + list(APPEND srcs "mspi/mspi_timing_tuning/mspi_timing_tuning.c") if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY) - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") endif() if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") endif() if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) - list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") + list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") endif() endif() endif() @@ -198,7 +203,8 @@ endif() set(public_include_dirs "include" "include/soc" "dma/include" "ldo/include" "debug_probe/include" "etm/include" - "mspi_timing_tuning/include" "mspi_timing_tuning/tuning_scheme_impl/include" + "mspi/mspi_timing_tuning/include" "mspi/mspi_timing_tuning/tuning_scheme_impl/include" + "mspi/mspi_intr/include" "power_supply/include" "modem/include") if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/include/soc/${target}") @@ -223,12 +229,12 @@ idf_component_register(SRCS ${srcs} PRIV_INCLUDE_DIRS port/include include/esp_private REQUIRES ${requires} PRIV_REQUIRES "${priv_requires}" - LDFRAGMENTS linker.lf dma/linker.lf ldo/linker.lf mspi_timing_tuning/linker.lf) + LDFRAGMENTS linker.lf dma/linker.lf ldo/linker.lf mspi/linker.lf) idf_build_get_property(target IDF_TARGET) add_subdirectory(port/${target}) if(CONFIG_SOC_SPI_MEM_SUPPORT_TIMING_TUNING) - add_subdirectory(mspi_timing_tuning/port/${target}) + add_subdirectory(mspi/mspi_timing_tuning/port/${target}) endif() add_subdirectory(lowpower) diff --git a/components/esp_hw_support/README.md b/components/esp_hw_support/README.md index 5a95217589..3082d1ab56 100644 --- a/components/esp_hw_support/README.md +++ b/components/esp_hw_support/README.md @@ -85,3 +85,126 @@ There may be multiple GDMA instances on a chip, some is attached to the AHB bus Some high-performance peripherals, such as MIPI, require DMA to provide more functions, such as hardware handshake mechanism, address growth mode, out-of-order transmission and so on. Therefore, a new DMA controller, called `DW_GDMA` was born. The prefix *DW* is taken from *DesignWare*. Please note that the specific DMA controller to be used for peripherals is determined by the specific chip. It is possible that, on chip A, SPI works with AHB GDMA, while on chip B, SPI works with AXI GDMA. + + +## MSPI Interrupt Logic - Chip Differences Analysis + +### 1. Overview + +This document describes the implementation differences of MSPI interrupt handling mechanism across different chips in ESP-IDF. + +#### Related Files + +| File | Description | +|------|-------------| +| `components/esp_hw_support/mspi/mspi_intr/mspi_intr.c` | Shared MSPI interrupt management | +| `components/esp_psram/system_layer/esp_psram_mspi.c` | PSRAM specific interrupt handling | + +--- + +### 2. Architecture Design + +The MSPI interrupt system is divided into two modes based on chip characteristics: + +| Mode | Description | +|------------------|--------------------------------------------------| +| **Shared IRQ** | Flash and PSRAM share a single MSPI IRQ source | +| **Separate IRQ** | Flash and PSRAM have independent MSPI IRQs | + +#### Architecture Diagrams + +##### 2.1 Shared IRQ Mode + +``` + ┌──────────────────────────────────────┐ + │ MSPI Hardware IRQ │ + └──────────────────┬───────────────────┘ + │ + ▼ + ┌──────────────────────────────────────┐ + │ mspi_isr_handler() │ + │ [mspi_intr.c] │ + │ │ + │ 1. mspi_ll_get_intr_raw() │ + │ 2. mspi_ll_clear_intr() │ + │ 3. Check error events and log │ + └──────────────────┬───────────────────┘ + │ + ┌──────────────────┴───────────────────┐ + │ │ + ▼ ▼ + ┌───────────────────┐ ┌───────────────────┐ + │ s_isr.psram_isr │ │ s_isr.flash_isr │ + │ (PSRAM handler) │ │ (Flash handler) │ + └─────────┬─────────┘ └─────────┬─────────┘ + │ │ + └────────────┬─────────────────────┘ + ▼ + ┌─────────────────────────┐ + │ abort() if fatal error │ + └─────────────────────────┘ +``` + +##### 2.2 Separate IRQ Mode + +``` + ┌─────────────────────┐ ┌─────────────────────┐ + │ Flash MSPI IRQ │ │ PSRAM MSPI IRQ │ + └──────────┬──────────┘ └──────────┬──────────┘ + │ │ + ▼ ▼ + ┌─────────────────────────────┐ ┌─────────────────────────────┐ + │ [Reserved] │ │ mspi_psram_isr_handler_ │ + │ │ │ wrapper() │ + │ To be registered by flash │ │ [esp_psram_mspi.c] │ + │ driver or system component │ │ │ + │ │ │ 1. psram_ctrlr_ll_get_ │ + │ Events to handle: │ │ intr_raw() │ + │ - MSPI0 CPU read events │ │ 2. psram_ctrlr_ll_clear_ │ + │ - MSPI1 ESP-Flash driver │ │ intr() │ + │ events │ │ 3. mspi_psram_isr_handler() │ + │ │ │ 4. abort() if fatal error │ + └─────────────────────────────┘ └─────────────────────────────┘ +``` + +--- + +### 3. API Reference + +#### 3.1 mspi_intr.c + +This file (and these APIs) is only available on MSPI_LL_INTR_SHARED chips + +```c +/** + * @brief Register MSPI ISR + * @param isr Pointer to structure containing psram_isr and flash_isr + * @return ESP_OK on success + */ +esp_err_t esp_mspi_register_isr(mspi_isr_t *isr); + +/** + * @brief Unregister MSPI ISR + * @return ESP_OK on success + */ +esp_err_t esp_mspi_unregister_isr(void); +``` + +#### 3.2 esp_psram_mspi.c + +- On MSPI_LL_INTR_SHARED chips, this file registers PSRAM specific ISR to the shared MSPI dispatcher (in mspi_intr.c) +- On !MSPI_LL_INTR_SHARED chips, this file registers PSRAM own ISR via interrupt allocator + +```c +/** + * @brief Register PSRAM MSPI ISR + * @return ESP_OK on success + */ +esp_err_t esp_psram_mspi_register_isr(void); + +/** + * @brief Unregister PSRAM MSPI ISR + * @return ESP_OK on success + */ +esp_err_t esp_psram_mspi_unregister_isr(void); +``` diff --git a/components/esp_hw_support/mspi_timing_tuning/linker.lf b/components/esp_hw_support/mspi/linker.lf similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/linker.lf rename to components/esp_hw_support/mspi/linker.lf diff --git a/components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h b/components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h new file mode 100644 index 0000000000..b40c234ccf --- /dev/null +++ b/components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief MSPI ISR + */ +typedef struct mspi_isr_s { + /** + * @brief MSPI PSRAM ISR + * + * @param[in] arg Argument to the ISR + * @param[in] intr_events Interrupt events + */ + void (*psram_isr)(void *arg, uint32_t intr_events); + + /** + * @brief MSPI Flash ISR + * + * @param[in] arg Argument to the ISR + * @param[in] intr_events Interrupt events + */ + void (*flash_isr)(void *arg, uint32_t intr_events); +} mspi_isr_t; + +/** + * @brief Register MSPI interrupt + * @note ISR dispatcher will decide if abort, dispatched ISRs should not abort + * + * This ISR mainly: + * - Report MSPI bus errors, e.g. fifo overflow, underflow. + * - ECC error, which will be useful for a Nand flash replacement mechanism. + * - etc. + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_mspi_register_isr(mspi_isr_t *isr); + +/** + * @brief Unregister MSPI interrupt + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_mspi_unregister_isr(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/mspi/mspi_intr/mspi_intr.c b/components/esp_hw_support/mspi/mspi_intr/mspi_intr.c new file mode 100644 index 0000000000..16d0488eaa --- /dev/null +++ b/components/esp_hw_support/mspi/mspi_intr/mspi_intr.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_intr_alloc.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_periph.h" +#include "esp_private/startup_internal.h" +#include "esp_private/mspi_intr.h" + +#if MSPI_LL_INTR_EVENT_SUPPORTED && MSPI_LL_INTR_SHARED + +#if CONFIG_ESP_PANIC_HANDLER_IRAM +#define MSPI_ISR_ATTR IRAM_ATTR +#define MSPI_ISR_FLAGS ESP_INTR_FLAG_IRAM +#else +#define MSPI_ISR_ATTR +#define MSPI_ISR_FLAGS 0 +#endif + +ESP_LOG_ATTR_TAG_DRAM(TAG, "mspi_intr"); +static intr_handle_t s_intr_handle = NULL; +static volatile mspi_isr_t s_isr = { + NULL, + NULL, +}; + +static void MSPI_ISR_ATTR mspi_isr_handler(void *arg) +{ + uint32_t intr_events = mspi_ll_get_intr_raw(MSPI_TIMING_LL_MSPI_ID_0); + mspi_ll_clear_intr(MSPI_TIMING_LL_MSPI_ID_0, intr_events); + + ESP_DRAM_LOGE(TAG, "MSPI error"); + ESP_DRAM_LOGD(TAG, "intr_events: 0x%" PRIx32, intr_events); + + bool is_ecc_error = false; + +#if MSPI_LL_ECC_INT_SUPPORTED + if (intr_events & MSPI_LL_EVENT_ECC_ERR) { + ESP_DRAM_LOGD(TAG, "ecc error"); + is_ecc_error = true; + } +#endif +#if MSPI_LL_PMS_INT_SUPPORTED + if (intr_events & MSPI_LL_EVENT_PMS_REJECT) { + ESP_DRAM_LOGE(TAG, "pms reject"); + } +#endif +#if MSPI_LL_ADDR_INT_SUPPORTED + if (intr_events & MSPI_LL_EVENT_AXI_RADDR_ERR) { + ESP_DRAM_LOGE(TAG, "read addr error"); + } + if (intr_events & MSPI_LL_EVENT_AXI_WADDR_ERR) { + ESP_DRAM_LOGE(TAG, "write addr error"); + } + if (intr_events & MSPI_LL_EVENT_AXI_WR_FLASH_ERR) { + ESP_DRAM_LOGE(TAG, "write flash error"); + } +#endif +#if MSPI_LL_THRESH_INT_SUPPORTED + if (intr_events & MSPI_LL_EVENT_RX_TRANS_OVF) { + ESP_DRAM_LOGE(TAG, "rx trans overflow"); + } + if (intr_events & MSPI_LL_EVENT_TX_TRANS_UDF) { + ESP_DRAM_LOGE(TAG, "tx trans underflow"); + } +#endif + + if (s_isr.psram_isr) { + s_isr.psram_isr(arg, intr_events); + } + + if (s_isr.flash_isr) { + s_isr.flash_isr(arg, intr_events); + } + + // For ecc error, will handle in the flash/psram isr + if (!is_ecc_error) { + abort(); + } + + //no yield for now +} + +esp_err_t esp_mspi_register_isr(mspi_isr_t *isr) +{ + esp_err_t ret = ESP_FAIL; + + if (isr && isr->psram_isr) { + s_isr.psram_isr = isr->psram_isr; + } + + if (isr && isr->flash_isr) { + s_isr.flash_isr = isr->flash_isr; + } + + if (!s_intr_handle) { + ret = esp_intr_alloc(mspi_hw_info.instances[MSPI_TIMING_LL_MSPI_ID_0].irq, + MSPI_ISR_FLAGS, + mspi_isr_handler, + NULL, + &s_intr_handle); + + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to allocate MSPI flash interrupt"); + + mspi_ll_clear_intr(MSPI_TIMING_LL_MSPI_ID_0, MSPI_LL_EVENT_MASK); + mspi_ll_enable_intr(MSPI_TIMING_LL_MSPI_ID_0, MSPI_LL_EVENT_MASK, true); + } + + return ESP_OK; +} + +esp_err_t esp_mspi_unregister_isr(void) +{ + esp_err_t ret = ESP_FAIL; + + if (s_intr_handle == NULL) { + ESP_EARLY_LOGE(TAG, "MSPI interrupt not registered"); + return ESP_ERR_INVALID_STATE; + } + + ret = esp_intr_free(s_intr_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to free MSPI interrupt"); + + s_isr.psram_isr = NULL; + s_isr.flash_isr = NULL; + + return ret; +} +#endif //#if MSPI_LL_INTR_EVENT_SUPPORTED && MSPI_LL_INTR_SHARED diff --git a/components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_config.h b/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_config.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h diff --git a/components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h b/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h diff --git a/components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_types.h b/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/include/esp_private/mspi_timing_types.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h diff --git a/components/esp_hw_support/mspi_timing_tuning/mspi_timing_tuning.c b/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/mspi_timing_tuning.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/CMakeLists.txt b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c5/CMakeLists.txt rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/CMakeLists.txt b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c61/CMakeLists.txt rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32p4/CMakeLists.txt b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32p4/CMakeLists.txt rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/CMakeLists.txt b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32s3/CMakeLists.txt rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c diff --git a/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c similarity index 100% rename from components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c rename to components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index b2118716d0..2b2ce2baec 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -18,7 +18,7 @@ endif() set(srcs) if(CONFIG_SPIRAM) - list(APPEND srcs "system_layer/esp_psram.c") + list(APPEND srcs "system_layer/esp_psram.c" "system_layer/esp_psram_mspi.c") if(${target} STREQUAL "esp32") list(APPEND srcs "esp32/esp_psram_extram_cache.c" diff --git a/components/esp_psram/README.md b/components/esp_psram/README.md new file mode 100644 index 0000000000..443af3f979 --- /dev/null +++ b/components/esp_psram/README.md @@ -0,0 +1,16 @@ +# PSRAM MSPI Interrupt Handling + +## Overview + +This file (`system_layer/esp_psram_mspi.c`) handles PSRAM-specific MSPI interrupt registration. + +| Chip Type | `MSPI_LL_INTR_SHARED` | Behavior | +|--------------|-----------------------|------------------------------------------------------| +| Shared IRQ | 1 | Register to shared MSPI dispatcher | +| Separate IRQ | 0 | Register standalone PSRAM ISR via `esp_intr_alloc()` | + +## Documentation + +For detailed architecture, flow diagrams, and API reference, see: + +**[esp_hw_support/README.md - MSPI Interrupt Logic](../esp_hw_support/README.md#mspi-interrupt-logic---chip-differences-analysis)** diff --git a/components/esp_psram/include/esp_private/esp_psram_mspi.h b/components/esp_psram/include/esp_private/esp_psram_mspi.h new file mode 100644 index 0000000000..849a0cdc38 --- /dev/null +++ b/components/esp_psram/include/esp_private/esp_psram_mspi.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Register MSPI PSRAM interrupt + * + * This ISR mainly: + * - Report MSPI bus errors, e.g. fifo overflow, underflow. For example, when data: + * - peripheral -> dma -> mspi -> psram, if the mspi fifo is empty, there will be a fifo underflow error.) + * - peripheral <- dma <- mspi <- psram, if the mspi fifo is full, there will be a fifo overflow error.) + * - etc. + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_psram_mspi_register_isr(void); + +/** + * @brief Unregister MSPI PSRAM interrupt + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_psram_mspi_unregister_isr(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_psram/system_layer/esp_psram.c b/components/esp_psram/system_layer/esp_psram.c index 38aec72f7b..de1bbc9039 100644 --- a/components/esp_psram/system_layer/esp_psram.c +++ b/components/esp_psram/system_layer/esp_psram.c @@ -28,6 +28,7 @@ #include "esp_private/esp_psram_extram.h" #include "esp_private/esp_mmu_map_private.h" #include "esp_private/esp_psram_impl.h" +#include "esp_private/esp_psram_mspi.h" #include "esp_private/startup_internal.h" #if SOC_SPIRAM_XIP_SUPPORTED #include "esp_private/mmu_psram_flash.h" @@ -111,8 +112,10 @@ typedef struct { static psram_ctx_t s_psram_ctx; static const DRAM_ATTR char TAG[] = "esp_psram"; -ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) +ESP_SYSTEM_INIT_FN(psram_core_stage_init, CORE, BIT(0), 103) { + esp_err_t ret = ESP_FAIL; + #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) #if (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL <= 100) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL <= 100) @@ -120,8 +123,8 @@ ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for security sensitive data e.g., TLS stack allocations (CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC)"); #endif if (esp_psram_is_initialized()) { - esp_err_t r = esp_psram_extram_add_to_heap_allocator(); - if (r != ESP_OK) { + ret = esp_psram_extram_add_to_heap_allocator(); + if (ret != ESP_OK) { ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!"); abort(); } @@ -130,7 +133,14 @@ ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) #endif } #endif - return ESP_OK; + + ret = esp_psram_mspi_register_isr(); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Failed to register PSRAM ISR!"); + abort(); + } + + return ret; } #if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_psram/system_layer/esp_psram_mspi.c b/components/esp_psram/system_layer/esp_psram_mspi.c new file mode 100644 index 0000000000..63b3481db7 --- /dev/null +++ b/components/esp_psram/system_layer/esp_psram_mspi.c @@ -0,0 +1,126 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +* +* SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_intr_alloc.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_periph.h" +#include "esp_private/mspi_intr.h" +#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S2 +#include "hal/psram_ctrlr_ll.h" +#endif + +#if PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED + +#if CONFIG_ESP_PANIC_HANDLER_IRAM +#define PSRAM_ISR_ATTR IRAM_ATTR +#define PSRAM_ISR_FLAGS ESP_INTR_FLAG_IRAM +#else +#define PSRAM_ISR_ATTR +#define PSRAM_ISR_FLAGS 0 +#endif + +ESP_LOG_ATTR_TAG_DRAM(TAG, "psram_mspi"); + +static void PSRAM_ISR_ATTR mspi_psram_isr_handler(void *arg, uint32_t intr_events) +{ +#if PSRAM_CTRLR_LL_PMS_INT_SUPPORTED + if (intr_events & PSRAM_CTRLR_LL_EVENT_PMS_REJECT) { + ESP_DRAM_LOGE(TAG, "psram pms reject"); + } +#endif +#if PSRAM_CTRLR_LL_THRESH_INT_SUPPORTED + if (intr_events & PSRAM_CTRLR_LL_EVENT_RX_TRANS_OVF) { + ESP_DRAM_LOGE(TAG, "psram rx trans overflow"); + } + if (intr_events & PSRAM_CTRLR_LL_EVENT_TX_TRANS_UDF) { + ESP_DRAM_LOGE(TAG, "psram tx trans underflow"); + } +#endif +} + +#if !MSPI_LL_INTR_SHARED +/** + * For PSRAM/FLASH separate MSPI chips, register a PSRAM standalone ISR + */ +__attribute__((__unused__)) static intr_handle_t s_mspi_psram_intr_handle = NULL; + +static void PSRAM_ISR_ATTR mspi_psram_isr_handler_wrapper(void *arg) +{ + uint32_t intr_events = psram_ctrlr_ll_get_intr_raw(PSRAM_CTRLR_LL_MSPI_ID_SYSTEM); + psram_ctrlr_ll_clear_intr(PSRAM_CTRLR_LL_MSPI_ID_SYSTEM, intr_events); + + ESP_DRAM_LOGE(TAG, "MSPI PSRAM error"); + + mspi_psram_isr_handler(arg, intr_events); + + abort(); +} +#endif + +esp_err_t esp_psram_mspi_register_isr(void) +{ + esp_err_t ret = ESP_FAIL; + +#if MSPI_LL_INTR_SHARED + mspi_isr_t isr = { + .psram_isr = mspi_psram_isr_handler, + }; + ret = esp_mspi_register_isr(&isr); +#else + ret = esp_intr_alloc(mspi_hw_info.instances[PSRAM_CTRLR_LL_MSPI_ID_SYSTEM].irq, + PSRAM_ISR_FLAGS, + mspi_psram_isr_handler_wrapper, + NULL, + &s_mspi_psram_intr_handle); + + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to allocate MSPI psram interrupt"); + + psram_ctrlr_ll_clear_intr(PSRAM_CTRLR_LL_MSPI_ID_SYSTEM, PSRAM_CTRLR_LL_EVENT_MASK); + psram_ctrlr_ll_enable_intr(PSRAM_CTRLR_LL_MSPI_ID_SYSTEM, PSRAM_CTRLR_LL_EVENT_MASK, true); +#endif + + return ret; +} + +esp_err_t esp_psram_mspi_unregister_isr(void) +{ + esp_err_t ret = ESP_FAIL; + +#if MSPI_LL_INTR_SHARED + ret = esp_mspi_unregister_isr(); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to unregister MSPI psram interrupt"); +#else + + if (s_mspi_psram_intr_handle == NULL) { + ESP_EARLY_LOGE(TAG, "MSPI psram interrupt not registered"); + return ESP_ERR_INVALID_STATE; + } + + ret = esp_intr_free(s_mspi_psram_intr_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to free MSPI psram interrupt"); +#endif + + return ESP_OK; +} +#else +esp_err_t esp_psram_mspi_register_isr(void) +{ + return ESP_OK; +} + +esp_err_t esp_psram_mspi_unregister_isr(void) +{ + return ESP_OK; +} +#endif //#if PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED diff --git a/components/esp_system/startup_funcs.c b/components/esp_system/startup_funcs.c index c3e9de4734..478b99b38a 100644 --- a/components/esp_system/startup_funcs.c +++ b/components/esp_system/startup_funcs.c @@ -17,6 +17,7 @@ #include "esp_private/cache_utils.h" #include "spi_flash_mmap.h" #include "esp_flash_internal.h" +#include "esp_private/mspi_intr.h" #include "esp_newlib.h" #include "esp_xt_wdt.h" #include "esp_cpu.h" @@ -25,6 +26,7 @@ #include "hal/wdt_hal.h" #include "hal/uart_types.h" #include "hal/uart_ll.h" +#include "hal/mspi_ll.h" #include "freertos/FreeRTOS.h" #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE @@ -73,7 +75,7 @@ ESP_SYSTEM_INIT_FN(init_show_cpu_freq, CORE, BIT(0), 10) * as it is a critical module for device functioning. */ #if SOC_BOD_SUPPORTED && !CONFIG_SECURE_ENABLE_TEE -ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 104) +ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 105) { // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) -> // malloc (esp_libc) -> heap_caps_malloc (heap), so heap must be at least initialized @@ -98,7 +100,7 @@ ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 104) } #endif -ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 105) +ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 106) { esp_libc_time_init(); return ESP_OK; @@ -123,6 +125,13 @@ ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130) #if CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED esp_pm_flash_freq_limit_init(); #endif // CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED + + // Register MSPI Flash interrupt +#if MSPI_LL_INTR_EVENT_SUPPORTED && MSPI_LL_INTR_SHARED + esp_mspi_register_isr(NULL); +#endif + //else register flash standalone ISR to deal with CPU / API flash access + return ESP_OK; } #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index a359cb228d..22a2c7c733 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -42,13 +42,15 @@ CORE: 101: esp_timer_init_nonos in components/esp_timer/src/esp_timer_init.c on CORE: 102: init_libc in components/esp_libc/src/init.c on BIT(0) -# Add the psram to heap, psram vaddr region is reserved when initialising the heap, after -# psram is initialised (and necessary reservation for psram usage), the rest of the psram -# will be added to the heap -CORE: 103: add_psram_to_heap in components/esp_psram/system_layer/esp_psram.c on BIT(0) +# PSRAM core stage init, including +# - Add the psram to heap, psram vaddr region is reserved when initialising the heap, after +# psram is initialised (and necessary reservation for psram usage), the rest of the psram +# will be added to the heap +# - Register PSRAM ISR routine +CORE: 103: psram_core_stage_init in components/esp_psram/system_layer/esp_psram.c on BIT(0) -CORE: 104: init_brownout in components/esp_system/startup_funcs.c on BIT(0) -CORE: 105: init_newlib_time in components/esp_system/startup_funcs.c on BIT(0) +CORE: 105: init_brownout in components/esp_system/startup_funcs.c on BIT(0) +CORE: 106: init_newlib_time in components/esp_system/startup_funcs.c on BIT(0) # Peripheral-specific implementation operators should be filled first # Then register vfs console, and follow by esp_libc stdio initialization @@ -127,7 +129,7 @@ SECONDARY: 230: usb_serial_jtag_conn_status_init in components/esp_driver_usb_se # psram adjust timing point need a separate task which should be created at startup. # Valid only `CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR` is enabled. -SECONDARY: 240: psram_adjust_timing_point_via_temperature in components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c on BIT(0) +SECONDARY: 240: psram_adjust_timing_point_via_temperature in components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c on BIT(0) # Has to be the last step! # Now that the application is about to start, disable boot watchdog diff --git a/components/soc/esp32s31/register/soc/spi_mem_s_struct.h b/components/soc/esp32s31/register/soc/spi_mem_s_struct.h index 2d56a32858..023c68289e 100644 --- a/components/soc/esp32s31/register/soc/spi_mem_s_struct.h +++ b/components/soc/esp32s31/register/soc/spi_mem_s_struct.h @@ -3152,6 +3152,7 @@ typedef struct { volatile spi_mem_s_date_reg_t mem_date; } spi_mem_s_dev_t; +extern spi_mem_s_dev_t SPIMEM2; #ifndef __cplusplus _Static_assert(sizeof(spi_mem_s_dev_t) == 0x400, "Invalid size of spi_mem_s_dev_t structure");