diff --git a/components/hal/esp32p4/include/hal/lp_mailbox_ll.h b/components/hal/esp32p4/include/hal/lp_mailbox_ll.h index b92d308f862..e9eed3f09c9 100644 --- a/components/hal/esp32p4/include/hal/lp_mailbox_ll.h +++ b/components/hal/esp32p4/include/hal/lp_mailbox_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,26 @@ extern "C" { #endif +/** + * @brief Enable the mailbox peripheral clock. + * + * @param dev Pointer to the LP mailbox device structure. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_enable_clock(lp_mb_dev_t *dev) +{ + dev->reg_clk_en.reg_clk_en = 1; +} + +/** + * @brief Reset the mailbox peripheral registers. + * + * @param dev Pointer to the LP mailbox device structure. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_reset_register(lp_mb_dev_t *dev) +{ + (void) dev; +} + /** * @brief Get a message (32-bit value) from the LP mailbox. diff --git a/components/hal/esp32s31/include/hal/lp_mailbox_ll.h b/components/hal/esp32s31/include/hal/lp_mailbox_ll.h new file mode 100644 index 00000000000..0f51cd1bc44 --- /dev/null +++ b/components/hal/esp32s31/include/hal/lp_mailbox_ll.h @@ -0,0 +1,213 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-S31 LP Mailbox register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/lp_mailbox_struct.h" +#include "soc/lp_mailbox_reg.h" +#include "soc/lp_peri_clkrst_struct.h" +#include "hal/misc.h" +#include "esp_attr.h" + +#define LP_MAILBOX_LL_MSG_COUNT 16U + +typedef mb_dev_t lp_mb_dev_t; +extern lp_mb_dev_t LP_MAILBOX; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable the mailbox peripheral clock. + * + * @param dev Pointer to the LP mailbox device structure. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_enable_clock(lp_mb_dev_t *dev) +{ + LP_PERI_CLKRST.mailbox.lp_mailbox_clk_en = 1; + dev->reg_clk_en.reg_clk_en = 1; +} + +/** + * @brief Reset the mailbox peripheral registers. + * + * @param dev Pointer to the LP mailbox device structure. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_reset_register(lp_mb_dev_t *dev) +{ + LP_PERI_CLKRST.mailbox.lp_mailbox_rst_en = 1; + LP_PERI_CLKRST.mailbox.lp_mailbox_rst_en = 0; +} + +/** + * @brief Get a message (32-bit value) from the LP mailbox. + * + * @param dev Pointer to the LP mailbox device structure. + * @param index Index of the message to retrieve (must be less than LP_MAILBOX_LL_MSG_COUNT). + * + * @return The 32-bit message value at the specified index, or 0 if the index is out of range. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_message(lp_mb_dev_t *dev, int index) +{ + if (index < LP_MAILBOX_LL_MSG_COUNT) { + return (&dev->massege_0.val)[index]; + } + return 0; +} + +/** + * @brief Set a message in the LP mailbox. + * + * @note Writing a message in the mailbox will set the corresponding message's intr_raw bit for + * both the LP and HP registers, regardless of the writer! + * + * @param dev Pointer to the LP mailbox device structure. + * @param index Index of the message to set (must be less than LP_MAILBOX_LL_MSG_COUNT). + * @param val Message (32-bit value) to write to the specified message index. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_set_message(lp_mb_dev_t *dev, int index, uint32_t val) +{ + if (index < LP_MAILBOX_LL_MSG_COUNT) { + (&dev->massege_0.val)[index] = val; + } +} + +/** + * @brief Get the raw status of the LP core interrupt register. + * + * @param dev Pointer to the LP mailbox device structure. + * + * @return Raw interrupt status value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_lp_intr_raw(lp_mb_dev_t *dev) +{ + return dev->lp_int_raw.val; +} + +/** + * @brief Clear LP core interrupt register bits. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to clear, bit `i` represents message `i`. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_lp_intr_clear(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->lp_int_clr.val = mask; +} + +/** + * @brief Get the LP core interrupt register status. + * + * @param dev Pointer to the LP mailbox device structure. + * + * @return Interrupt status value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_status(lp_mb_dev_t *dev) +{ + return dev->lp_int_st.val; +} + +/** + * @brief Enable mailbox interrupts by mask for the LP core. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to enable, bit `i` represents message `i`. + * + * @return Updated interrupt enable register value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_enable_mask(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->lp_int_ena.val |= mask; + return dev->lp_int_ena.val; +} + +/** + * @brief Disable LP core mailbox interrupts by mask. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to disable, bit `i` represents message `i`. + * + * @return Updated interrupt enable register value. + */ + +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_disable_mask(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->lp_int_ena.val &= ~mask; + return dev->lp_int_ena.val; +} + +/** + * @brief Get the raw status of the HP core interrupt register. + * + * @param dev Pointer to the LP mailbox device structure. + * + * @return Raw interrupt status value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_hp_intr_raw(lp_mb_dev_t *dev) +{ + return dev->hp_int_raw.val; +} + +/** + * @brief Clear HP core interrupt register bits. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to clear, bit `i` represents message `i`. + */ +FORCE_INLINE_ATTR void lp_mailbox_ll_hp_intr_clear(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->hp_int_clr.val = mask; +} + +/** + * @brief Get the HP core interrupt register status. + * + * @param dev Pointer to the LP mailbox device structure. + * + * @return Interrupt status value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_status(lp_mb_dev_t *dev) +{ + return dev->hp_int_st.val; +} + +/** + * @brief Enable mailbox interrupts by mask for the HP core. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to enable, bit `i` represents message `i`. + * + * @return Updated interrupt enable register value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_enable_mask(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->hp_int_ena.val |= mask; + return dev->hp_int_ena.val; +} + +/** + * @brief Disable HP core mailbox interrupts by mask. + * + * @param dev Pointer to the LP mailbox device structure. + * @param mask Bitmask of interrupts to disable, bit `i` represents message `i`. + * + * @return Updated interrupt enable register value. + */ +FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_disable_mask(lp_mb_dev_t *dev, uint32_t mask) +{ + dev->hp_int_ena.val &= ~mask; + return dev->hp_int_ena.val; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 3ea2ff0aa3c..47973ee3cb2 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -1187,6 +1187,10 @@ config SOC_PM_RETENTION_MODULE_NUM int default 64 +config SOC_LP_MAILBOX_SUPPORTED + bool + default y + config SOC_LP_CORE_SUPPORT_ETM bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 1abda0792cc..904eca6fa1b 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -473,7 +473,7 @@ #define SOC_PM_RETENTION_MODULE_NUM (64) /*-------------------------- LP_CORE CAPS ------------------------------------*/ -// #define SOC_LP_MAILBOX_SUPPORTED (1) // TODO: [ESP32S31] IDF-14637 +#define SOC_LP_MAILBOX_SUPPORTED (1) /*!< LP Core supports LP-mailbox */ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM wakeup */ #define SOC_LP_CORE_CONFIGURABLE_BOOT_ADDR (1) /*!< LP Core has no LP ROM; HP must write the reset_vector address (LP_RAM_BASE+0x80) to LP_SYS.lp_core_boot_addr before triggering LP wake */ //#define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ TODO IDF-14635 diff --git a/components/ulp/lp_core/lp_core/lp_core_mailbox.c b/components/ulp/lp_core/lp_core/lp_core_mailbox.c index 3c7458ca467..c19d2894684 100644 --- a/components/ulp/lp_core/lp_core/lp_core_mailbox.c +++ b/components/ulp/lp_core/lp_core/lp_core_mailbox.c @@ -158,6 +158,7 @@ esp_err_t lp_core_mailbox_init(lp_mailbox_t *mailbox, lp_mailbox_config_t *confi return ESP_ERR_INVALID_STATE; } hal_memset(&s_mailbox, 0, sizeof(s_mailbox)); + lp_core_mailbox_impl_init(); s_mailbox.mb_ctx = lp_core_mailbox_impl_get_context(); if (s_mailbox.mb_ctx == NULL) { return ESP_ERR_INVALID_STATE; diff --git a/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_hw.c b/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_hw.c index 7a1b6e8541f..c24765cc0b5 100644 --- a/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_hw.c +++ b/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_hw.c @@ -16,6 +16,12 @@ /* Implementation agnostic interrupt handler */ static void (*s_intr_handler)(void); +void lp_core_mailbox_impl_init(void) +{ + lp_mailbox_ll_enable_clock(&LP_MAILBOX); + lp_mailbox_ll_reset_register(&LP_MAILBOX); +} + void LP_CORE_ISR_ATTR ulp_lp_core_mailbox_intr_handler(void) { if (s_intr_handler) { diff --git a/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_sw.c b/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_sw.c index 9794ef1ea42..cba93407bb7 100644 --- a/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_sw.c +++ b/components/ulp/lp_core/lp_core/port/lp_core_mailbox_impl_sw.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 */ @@ -30,6 +30,14 @@ lp_core_mailbox_impl_sw_t g_lp_core_mailbox_impl_sw_ctx; /* Implementation agnostic interrupt handler */ static void (*s_intr_handler)(void); +void lp_core_mailbox_impl_init(void) +{ + /* This structure must be initialized by the LP core */ + memset(&g_lp_core_mailbox_impl_sw_ctx, 0, sizeof(g_lp_core_mailbox_impl_sw_ctx)); + ulp_lp_core_spinlock_init(&g_lp_core_mailbox_impl_sw_ctx.lock); + ulp_lp_core_sw_intr_from_hp_enable(false); +} + void LP_CORE_ISR_ATTR ulp_lp_core_sw_intr_handler(void) { if (s_intr_handler) { @@ -39,10 +47,6 @@ void LP_CORE_ISR_ATTR ulp_lp_core_sw_intr_handler(void) lp_core_mailbox_ctx_t lp_core_mailbox_impl_get_context(void) { - /* This structure must be initialized by the LP core */ - memset(&g_lp_core_mailbox_impl_sw_ctx, 0, sizeof(g_lp_core_mailbox_impl_sw_ctx)); - ulp_lp_core_spinlock_init(&g_lp_core_mailbox_impl_sw_ctx.lock); - ulp_lp_core_sw_intr_from_hp_enable(false); return (lp_core_mailbox_ctx_t) &g_lp_core_mailbox_impl_sw_ctx; } diff --git a/components/ulp/lp_core/lp_core_mailbox.c b/components/ulp/lp_core/lp_core_mailbox.c index 1947a2351d5..a7620511399 100644 --- a/components/ulp/lp_core/lp_core_mailbox.c +++ b/components/ulp/lp_core/lp_core_mailbox.c @@ -162,6 +162,7 @@ esp_err_t lp_core_mailbox_init(lp_mailbox_t *mailbox, lp_mailbox_config_t *confi return ESP_ERR_INVALID_ARG; } + lp_core_mailbox_impl_init(); lp_core_mailbox_ctx_t context = lp_core_mailbox_impl_get_context(); if (context == NULL) { /* Invalid state! LP core didn't initialize the spinlock? (SW backend) */ diff --git a/components/ulp/lp_core/lp_core_mailbox_impl_hw.c b/components/ulp/lp_core/lp_core_mailbox_impl_hw.c index 7619a7408ae..0a9b9ab35c5 100644 --- a/components/ulp/lp_core/lp_core_mailbox_impl_hw.c +++ b/components/ulp/lp_core/lp_core_mailbox_impl_hw.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 */ @@ -11,6 +11,11 @@ #include "ulp_lp_core_mailbox_impl_shared.h" #include "hal/lp_mailbox_ll.h" +void lp_core_mailbox_impl_init(void) +{ + lp_mailbox_ll_enable_clock(&LP_MAILBOX); +} + /* Mailbox hardware controller, used as a context */ lp_core_mailbox_ctx_t lp_core_mailbox_impl_get_context(void) { diff --git a/components/ulp/lp_core/lp_core_mailbox_impl_sw.c b/components/ulp/lp_core/lp_core_mailbox_impl_sw.c index 4bdacbd0f24..ccc1196c871 100644 --- a/components/ulp/lp_core/lp_core_mailbox_impl_sw.c +++ b/components/ulp/lp_core/lp_core_mailbox_impl_sw.c @@ -26,6 +26,10 @@ typedef struct { /* The structure above is defined by the ULP */ extern lp_core_mailbox_impl_sw_t ulp_g_lp_core_mailbox_impl_sw_ctx; +void lp_core_mailbox_impl_init(void) +{ +} + lp_core_mailbox_ctx_t lp_core_mailbox_impl_get_context(void) { /* Make sure the LP core initialized the spinlock */ diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_mailbox_impl_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_mailbox_impl_shared.h index d0964d5f9fe..bcc9a5f5487 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_mailbox_impl_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_mailbox_impl_shared.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,11 @@ typedef intptr_t lp_message_t; */ typedef void* lp_core_mailbox_ctx_t; +/** + * @brief Initialize the mailbox implementation for the current target/core. + */ +void lp_core_mailbox_impl_init(void); + /** * @brief Get the mailbox context for the current implementation */ diff --git a/docs/doxygen/Doxyfile_esp32s31 b/docs/doxygen/Doxyfile_esp32s31 index f035112c1ed..df2f1528909 100644 --- a/docs/doxygen/Doxyfile_esp32s31 +++ b/docs/doxygen/Doxyfile_esp32s31 @@ -23,5 +23,6 @@ INPUT += \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_mailbox.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h \ $(PROJECT_PATH)/components/ulp/ulp_common/include/ulp_common.h \ diff --git a/examples/system/ulp/.build-test-rules.yml b/examples/system/ulp/.build-test-rules.yml index d2635ed919f..3ef1abb041d 100644 --- a/examples/system/ulp/.build-test-rules.yml +++ b/examples/system/ulp/.build-test-rules.yml @@ -72,9 +72,7 @@ examples/system/ulp/lp_core/lp_i2c: examples/system/ulp/lp_core/lp_mailbox: enable: - - if: SOC_LP_CORE_SUPPORTED == 1 and IDF_TARGET not in ["esp32s31"] - temporary: true - reason: ESP32-S31 not supported yet # TODO: [ESP32S31] IDF-14637 + - if: SOC_LP_CORE_SUPPORTED == 1 <<: *ulp_default_depends examples/system/ulp/lp_core/lp_spi: diff --git a/examples/system/ulp/lp_core/lp_mailbox/README.md b/examples/system/ulp/lp_core/lp_mailbox/README.md index ef550c7b33b..bb51c829846 100644 --- a/examples/system/ulp/lp_core/lp_mailbox/README.md +++ b/examples/system/ulp/lp_core/lp_mailbox/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | ESP32-S31 | +| ----------------- | -------- | -------- | -------- | --------- | # LP Mailbox Example diff --git a/examples/system/ulp/lp_core/lp_mailbox/pytest_lp_mailbox.py b/examples/system/ulp/lp_core/lp_mailbox/pytest_lp_mailbox.py index d206a9ddb20..9010bb7522b 100644 --- a/examples/system/ulp/lp_core/lp_mailbox/pytest_lp_mailbox.py +++ b/examples/system/ulp/lp_core/lp_mailbox/pytest_lp_mailbox.py @@ -8,9 +8,6 @@ from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic @idf_parametrize('target', soc_filtered_targets('SOC_LP_CORE_SUPPORTED == 1'), indirect=['target']) -@pytest.mark.temp_skip_ci( - targets=['esp32s31'], reason='s31 bringup on this module is not done, TODO: [ESP32S31] IDF-14637' -) def test_lp_mailbox(dut: Dut) -> None: # Wait for LP core to be loaded and running dut.expect_exact('LP Mailbox initialized successfully')