From c002cb67d192dbb2a30cc2ab400589a8002fbb77 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Thu, 8 Jan 2026 11:07:37 +0100 Subject: [PATCH] fix(lp_mailbox): Fixed LP mailbox operation when LP core interrupts are enabled This commit fixes the following issues with the LP mailbox when LP core interrupts are enabled - 1. Removed static storage classifier on the interrupt handler to remove internal linkage and allow the linker to override the weak symbol. 2. Fixed a bug in the interrupt handler where the ACK bit interrupt was not being cleared correctly. 3. Fixed a bug in the LP core interrupt handler where the message mask was not being set correctly. Closes https://github.com/espressif/esp-idf/issues/18095 --- components/ulp/lp_core/lp_core/lp_core_mailbox.c | 9 +++++---- .../ulp/lp_core/lp_core/port/lp_core_mailbox_impl_hw.c | 8 +++++--- .../ulp/lp_core/lp_core/port/lp_core_mailbox_impl_sw.c | 2 +- components/ulp/lp_core/lp_core_mailbox.c | 9 +++++---- 4 files changed, 16 insertions(+), 12 deletions(-) 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 0392f865b7..3c7458ca46 100644 --- a/components/ulp/lp_core/lp_core/lp_core_mailbox.c +++ b/components/ulp/lp_core/lp_core/lp_core_mailbox.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 */ @@ -95,7 +95,7 @@ static inline bool lp_core_mailbox_check_timeout(uint32_t start_cycle, int32_t t static void ulp_lp_core_mailbox_intr_handler(void) { - lp_message_t received[LP_MAILBOX_RX_MSG_COUNT]; + lp_message_t received[LP_MAILBOX_RX_MSG_COUNT / 2]; int received_count = 0; /* `s_isr_arg` cannot be NULL but let's be safe and test it */ @@ -109,14 +109,15 @@ static void ulp_lp_core_mailbox_intr_handler(void) uint32_t clr_mask = 0; for (int i = 0; i < LP_MAILBOX_RX_MSG_COUNT; i += 2) { - const uint32_t mask = BIT(i); + const uint32_t mask = BIT(LP_MAILBOX_RX_MSG_IDX + i); if (status & mask) { clr_mask |= mask; received[received_count] = lp_core_mailbox_impl_get_message(s_isr_arg->mb_ctx, LP_MAILBOX_RX_MSG_IDX + i); /* Acknowledge reception */ const int ack_msg_idx = LP_MAILBOX_RX_MSG_IDX + lp_core_next_msg_idx(i); lp_core_mailbox_impl_set_message(s_isr_arg->mb_ctx, ack_msg_idx, LP_MAILBOX_ACK); - lp_core_mailbox_impl_intr_clear(s_isr_arg->mb_ctx, ack_msg_idx); + /* Clear ACK self-interrupt (writing ACK sets LP's own interrupt bit) */ + lp_core_mailbox_impl_intr_clear(s_isr_arg->mb_ctx, BIT(ack_msg_idx)); received_count++; /* We must not acknowledge more messages than what the caller needs */ s_isr_arg->rcv_remaining--; 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 8acefdc5c7..7a1b6e8541 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 @@ -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 */ @@ -16,9 +16,11 @@ /* Implementation agnostic interrupt handler */ static void (*s_intr_handler)(void); -static void LP_CORE_ISR_ATTR ulp_lp_core_mailbox_intr_handler(void) +void LP_CORE_ISR_ATTR ulp_lp_core_mailbox_intr_handler(void) { - s_intr_handler(); + if (s_intr_handler) { + s_intr_handler(); + } } lp_core_mailbox_ctx_t lp_core_mailbox_impl_get_context(void) 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 241172a36b..9794ef1ea4 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 @@ -30,7 +30,7 @@ lp_core_mailbox_impl_sw_t g_lp_core_mailbox_impl_sw_ctx; /* Implementation agnostic interrupt handler */ static void (*s_intr_handler)(void); -static void LP_CORE_ISR_ATTR ulp_lp_core_sw_intr_handler(void) +void LP_CORE_ISR_ATTR ulp_lp_core_sw_intr_handler(void) { if (s_intr_handler) { s_intr_handler(); diff --git a/components/ulp/lp_core/lp_core_mailbox.c b/components/ulp/lp_core/lp_core_mailbox.c index f0d03dd32a..1947a2351d 100644 --- a/components/ulp/lp_core/lp_core_mailbox.c +++ b/components/ulp/lp_core/lp_core_mailbox.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 */ @@ -33,7 +33,7 @@ #define LP_MAILBOX_RX_MSG_COUNT (LP_MAILBOX_MSG_COUNT / 2) /** - * @brief Mask for the HP -> LP messages + * @brief Mask for the LP -> HP messages */ #define LP_MAILBOX_RX_MSG_MASK (((1U << LP_MAILBOX_RX_MSG_COUNT) - 1U) << LP_MAILBOX_RX_MSG_IDX) @@ -106,7 +106,7 @@ static void lp_core_mailbox_intr_handler(void* arg) portYIELD_FROM_ISR(); } } else { - lp_message_t received[LP_MAILBOX_RX_MSG_COUNT]; + lp_message_t received[LP_MAILBOX_RX_MSG_COUNT / 2]; int received_count = 0; /* Acknowledge all the received message as fast as possible */ @@ -123,7 +123,8 @@ static void lp_core_mailbox_intr_handler(void* arg) /* Acknowledge reception by writing to the next message */ const int ack_msg_idx = LP_MAILBOX_RX_MSG_IDX + lp_core_next_msg_idx(i); lp_core_mailbox_impl_set_message(mailbox->mb_ctx, ack_msg_idx, LP_MAILBOX_ACK); - lp_core_mailbox_impl_intr_clear(mailbox->mb_ctx, ack_msg_idx); + /* Clear ACK self-interrupt (writing ACK sets HP's own interrupt bit) */ + lp_core_mailbox_impl_intr_clear(mailbox->mb_ctx, BIT(ack_msg_idx)); received_count++; mailbox->rcv_remaining--; if (mailbox->rcv_remaining == 0) {